Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New resource: aws_lambda_invocation #14388

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ func Provider() *schema.Provider {
"aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(),
"aws_lambda_function_event_invoke_config": resourceAwsLambdaFunctionEventInvokeConfig(),
"aws_lambda_function": resourceAwsLambdaFunction(),
"aws_lambda_invocation": resourceAwsLambdaInvocation(),
"aws_lambda_layer_version": resourceAwsLambdaLayerVersion(),
"aws_lambda_permission": resourceAwsLambdaPermission(),
"aws_lambda_provisioned_concurrency_config": resourceAwsLambdaProvisionedConcurrencyConfig(),
Expand Down
100 changes: 100 additions & 0 deletions aws/resource_aws_lambda_invocation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package aws

import (
"crypto/md5"
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lambda"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func resourceAwsLambdaInvocation() *schema.Resource {
return &schema.Resource{
Create: resourceAwsLambdaInvocationCreate,
Read: resourceAwsLambdaInvocationRead,
Update: resourceAwsLambdaInvocationUpdate,
Delete: resourceAwsLambdaInvocationDelete,

Schema: map[string]*schema.Schema{
"function_name": {
Type: schema.TypeString,
Required: true,
},

"qualifier": {
Type: schema.TypeString,
Optional: true,
Default: "$LATEST",
},

"input": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsJSON,
},

"invoke_on_update": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},

"result": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsLambdaInvocationCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).lambdaconn

functionName := d.Get("function_name").(string)
qualifier := d.Get("qualifier").(string)
input := []byte(d.Get("input").(string))

res, err := conn.Invoke(&lambda.InvokeInput{
FunctionName: aws.String(functionName),
InvocationType: aws.String(lambda.InvocationTypeRequestResponse),
Payload: input,
Qualifier: aws.String(qualifier),
})

if err != nil {
return err
}

if res.FunctionError != nil {
return fmt.Errorf("Lambda function (%s) returned error: (%s)", functionName, string(res.Payload))
}

if err = d.Set("result", string(res.Payload)); err != nil {
return err
}

d.SetId(fmt.Sprintf("%s_%s_%x", functionName, qualifier, md5.Sum(input)))

return nil
}

func resourceAwsLambdaInvocationRead(d *schema.ResourceData, meta interface{}) error {
return nil
}

func resourceAwsLambdaInvocationUpdate(d *schema.ResourceData, meta interface{}) error {
if d.Get("invoke_on_update").(bool) {
return resourceAwsLambdaInvocationCreate(d, meta)
} else {
return nil
}
}

func resourceAwsLambdaInvocationDelete(d *schema.ResourceData, meta interface{}) error {
d.SetId("")
d.Set("result", nil)
return nil
}
195 changes: 195 additions & 0 deletions aws/resource_aws_lambda_invocation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccResourceAwsLambdaInvocation_basic(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
testData := "value3"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckLambdaInvocationDestroy,
Steps: []resource.TestStep{
{
Config: testAccResourceAwsLambdaInvocation_basic_config(rName, testData),
Check: resource.ComposeTestCheckFunc(
testAccCheckLambdaInvocationResult("aws_lambda_invocation.invocation_test", `{"key1":"value1","key2":"value2","key3":"`+testData+`"}`),
),
},
},
})
}

func TestAccResourceAwsLambdaInvocation_qualifier(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
testData := "value3"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckLambdaInvocationDestroy,
Steps: []resource.TestStep{
{
Config: testAccResourceAwsLambdaInvocation_qualifier_config(rName, testData),
Check: resource.ComposeTestCheckFunc(
testAccCheckLambdaInvocationResult("aws_lambda_invocation.invocation_test", `{"key1":"value1","key2":"value2","key3":"`+testData+`"}`),
),
},
},
})
}

func TestAccResourceAwsLambdaInvocation_complex(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
testData := "value3"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckLambdaInvocationDestroy,
Steps: []resource.TestStep{
{
Config: testAccResourceAwsLambdaInvocation_complex_config(rName, testData),
Check: resource.ComposeTestCheckFunc(
testAccCheckLambdaInvocationResult("aws_lambda_invocation.invocation_test", `{"key1":{"subkey1":"subvalue1"},"key2":{"subkey2":"subvalue2","subkey3":{"a": "b"}},"key3":"`+testData+`"}`),
),
},
},
})
}

func testAccCheckLambdaInvocationDestroy(s *terraform.State) error {
// Nothing to check on destroy
return nil

}

func testAccResourceAwsLambdaInvocation_base_config(roleName string) string {
return fmt.Sprintf(`
data "aws_iam_policy_document" "lambda_assume_role_policy" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}

resource "aws_iam_role" "lambda_role" {
name = "%s"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role_policy.json
}

resource "aws_iam_role_policy_attachment" "lambda_role_policy" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
role = aws_iam_role.lambda_role.name
}
`, roleName)
}

func testAccResourceAwsLambdaInvocation_basic_config(rName, testData string) string {
return fmt.Sprintf(testAccResourceAwsLambdaInvocation_base_config(rName)+`
resource "aws_lambda_function" "lambda" {
depends_on = ["aws_iam_role_policy_attachment.lambda_role_policy"]

filename = "test-fixtures/lambda_invocation.zip"
function_name = "%s"
role = aws_iam_role.lambda_role.arn
handler = "lambda_invocation.handler"
runtime = "nodejs12.x"

environment {
variables = {
TEST_DATA = "%s"
}
}
}

resource "aws_lambda_invocation" "invocation_test" {
function_name = aws_lambda_function.lambda.function_name

input = <<JSON
{
"key1": "value1",
"key2": "value2"
}
JSON
}
`, rName, testData)
}

func testAccResourceAwsLambdaInvocation_qualifier_config(rName, testData string) string {
return fmt.Sprintf(testAccResourceAwsLambdaInvocation_base_config(rName)+`
resource "aws_lambda_function" "lambda" {
depends_on = ["aws_iam_role_policy_attachment.lambda_role_policy"]

filename = "test-fixtures/lambda_invocation.zip"
function_name = "%s"
role = aws_iam_role.lambda_role.arn
handler = "lambda_invocation.handler"
runtime = "nodejs12.x"
publish = true

environment {
variables = {
TEST_DATA = "%s"
}
}
}

resource "aws_lambda_invocation" "invocation_test" {
function_name = aws_lambda_function.lambda.function_name
qualifier = aws_lambda_function.lambda.version

input = <<JSON
{
"key1": "value1",
"key2": "value2"
}
JSON
}
`, rName, testData)
}

func testAccResourceAwsLambdaInvocation_complex_config(rName, testData string) string {
return fmt.Sprintf(testAccResourceAwsLambdaInvocation_base_config(rName)+`
resource "aws_lambda_function" "lambda" {
depends_on = ["aws_iam_role_policy_attachment.lambda_role_policy"]

filename = "test-fixtures/lambda_invocation.zip"
function_name = "%s"
role = aws_iam_role.lambda_role.arn
handler = "lambda_invocation.handler"
runtime = "nodejs12.x"
publish = true

environment {
variables = {
TEST_DATA = "%s"
}
}
}

resource "aws_lambda_invocation" "invocation_test" {
function_name = aws_lambda_function.lambda.function_name

input = <<JSON
{
"key1": {"subkey1": "subvalue1"},
"key2": {"subkey2": "subvalue2", "subkey3": {"a": "b"}}
}
JSON
}
`, rName, testData)
}
44 changes: 44 additions & 0 deletions website/docs/r/lambda_invocation.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
subcategory: "Lambda"
layout: "aws"
page_title: "AWS: aws_lambda_invocation"
description: |-
Provide AWS Lambda Function result.
---

# Resource: aws_lambda_invocation

Use this resource to invoke custom lambda functions.
The lambda function is invoked with [RequestResponse](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax)
invocation type.

## Example Usage

```hcl
resource "aws_lambda_invocation" "example" {
function_name = "${aws_lambda_function.lambda_function_test.function_name}"

input = <<JSON
{
"key1": "value1",
"key2": "value2"
}
JSON
}

output "result_entry" {
value = jsondecode(aws_lambda_invocation.example.result)["key1"]
}
```

## Argument Reference

* `function_name` - (Required) The name of the lambda function.
* `input` - (Required) A string in JSON format that is passed as payload to the lambda function.
* `qualifier` - (Optional) The qualifier (a.k.a version) of the lambda function. Defaults
to `$LATEST`.
* `invoke_on_update` - (Optional) Whether to run the lambda function on argument changes. Default is `true`.

## Attributes Reference

* `result` - String result of the lambda function invocation.