Merge #12188: AWS Lambda DeadLetterConfig support
This commit is contained in:
commit
bc60bd4561
|
@ -58,6 +58,22 @@ func resourceAwsLambdaFunction() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
},
|
},
|
||||||
|
"dead_letter_config": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
MinItems: 0,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"target_arn": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ValidateFunc: validateArn,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"function_name": {
|
"function_name": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -222,6 +238,16 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
|
||||||
Publish: aws.Bool(d.Get("publish").(bool)),
|
Publish: aws.Bool(d.Get("publish").(bool)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("dead_letter_config"); ok {
|
||||||
|
dlcMaps := v.([]interface{})
|
||||||
|
if len(dlcMaps) == 1 { // Schema guarantees either 0 or 1
|
||||||
|
dlcMap := dlcMaps[0].(map[string]interface{})
|
||||||
|
params.DeadLetterConfig = &lambda.DeadLetterConfig{
|
||||||
|
TargetArn: aws.String(dlcMap["target_arn"].(string)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := d.GetOk("vpc_config"); ok {
|
if v, ok := d.GetOk("vpc_config"); ok {
|
||||||
config, err := validateVPCConfig(v)
|
config, err := validateVPCConfig(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -343,6 +369,16 @@ func resourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) err
|
||||||
log.Printf("[ERR] Error setting environment for Lambda Function (%s): %s", d.Id(), err)
|
log.Printf("[ERR] Error setting environment for Lambda Function (%s): %s", d.Id(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if function.DeadLetterConfig != nil && function.DeadLetterConfig.TargetArn != nil {
|
||||||
|
d.Set("dead_letter_config", []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"target_arn": *function.DeadLetterConfig.TargetArn,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
d.Set("dead_letter_config", []interface{}{})
|
||||||
|
}
|
||||||
|
|
||||||
// List is sorted from oldest to latest
|
// List is sorted from oldest to latest
|
||||||
// so this may get costly over time :'(
|
// so this may get costly over time :'(
|
||||||
var lastVersion, lastQualifiedArn string
|
var lastVersion, lastQualifiedArn string
|
||||||
|
@ -485,6 +521,16 @@ func resourceAwsLambdaFunctionUpdate(d *schema.ResourceData, meta interface{}) e
|
||||||
configReq.KMSKeyArn = aws.String(d.Get("kms_key_arn").(string))
|
configReq.KMSKeyArn = aws.String(d.Get("kms_key_arn").(string))
|
||||||
configUpdate = true
|
configUpdate = true
|
||||||
}
|
}
|
||||||
|
if d.HasChange("dead_letter_config") {
|
||||||
|
dlcMaps := d.Get("dead_letter_config").([]interface{})
|
||||||
|
if len(dlcMaps) == 1 { // Schema guarantees either 0 or 1
|
||||||
|
dlcMap := dlcMaps[0].(map[string]interface{})
|
||||||
|
configReq.DeadLetterConfig = &lambda.DeadLetterConfig{
|
||||||
|
TargetArn: aws.String(dlcMap["target_arn"].(string)),
|
||||||
|
}
|
||||||
|
configUpdate = true
|
||||||
|
}
|
||||||
|
}
|
||||||
if d.HasChange("environment") {
|
if d.HasChange("environment") {
|
||||||
if v, ok := d.GetOk("environment"); ok {
|
if v, ok := d.GetOk("environment"); ok {
|
||||||
environments := v.([]interface{})
|
environments := v.([]interface{})
|
||||||
|
|
|
@ -172,6 +172,37 @@ func TestAccAWSLambdaFunction_versioned(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSLambdaFunction_DeadLetterConfig(t *testing.T) {
|
||||||
|
var conf lambda.GetFunctionOutput
|
||||||
|
|
||||||
|
rSt := acctest.RandString(5)
|
||||||
|
rName := fmt.Sprintf("tf_test_%s", rSt)
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckLambdaFunctionDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSLambdaConfigWithDeadLetterConfig(rName, rSt),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf),
|
||||||
|
testAccCheckAwsLambdaFunctionName(&conf, rName),
|
||||||
|
testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName),
|
||||||
|
func(s *terraform.State) error {
|
||||||
|
if !strings.HasSuffix(*conf.Configuration.DeadLetterConfig.TargetArn, ":"+rName) {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"Expected DeadLetterConfig.TargetArn %s to have suffix %s", *conf.Configuration.DeadLetterConfig.TargetArn, ":"+rName,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSLambdaFunction_VPC(t *testing.T) {
|
func TestAccAWSLambdaFunction_VPC(t *testing.T) {
|
||||||
var conf lambda.GetFunctionOutput
|
var conf lambda.GetFunctionOutput
|
||||||
|
|
||||||
|
@ -681,6 +712,15 @@ resource "aws_iam_role_policy" "iam_policy_for_lambda" {
|
||||||
"Resource": [
|
"Resource": [
|
||||||
"*"
|
"*"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"SNS:Publish"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -879,6 +919,27 @@ resource "aws_lambda_function" "lambda_function_test" {
|
||||||
`, rName)
|
`, rName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccAWSLambdaConfigWithDeadLetterConfig(rName, rSt string) string {
|
||||||
|
return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+`
|
||||||
|
resource "aws_lambda_function" "lambda_function_test" {
|
||||||
|
filename = "test-fixtures/lambdatest.zip"
|
||||||
|
function_name = "%s"
|
||||||
|
role = "${aws_iam_role.iam_for_lambda.arn}"
|
||||||
|
handler = "exports.example"
|
||||||
|
runtime = "nodejs4.3"
|
||||||
|
|
||||||
|
dead_letter_config {
|
||||||
|
target_arn = "${aws_sns_topic.lambda_function_test.arn}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_sns_topic" "lambda_function_test" {
|
||||||
|
name = "%s"
|
||||||
|
}
|
||||||
|
|
||||||
|
`, rName, rName)
|
||||||
|
}
|
||||||
|
|
||||||
func testAccAWSLambdaConfigWithVPC(rName, rSt string) string {
|
func testAccAWSLambdaConfigWithVPC(rName, rSt string) string {
|
||||||
return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+`
|
return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+`
|
||||||
resource "aws_lambda_function" "lambda_function_test" {
|
resource "aws_lambda_function" "lambda_function_test" {
|
||||||
|
|
|
@ -57,6 +57,7 @@ resource "aws_lambda_function" "test_lambda" {
|
||||||
* `s3_key` - (Optional) The S3 key of a [zip file][2] containing your lambda function source code. Conflicts with `filename`.
|
* `s3_key` - (Optional) The S3 key of a [zip file][2] containing your lambda function source code. Conflicts with `filename`.
|
||||||
* `s3_object_version` - (Optional) The object version of your lambda function source code. Conflicts with `filename`.
|
* `s3_object_version` - (Optional) The object version of your lambda function source code. Conflicts with `filename`.
|
||||||
* `function_name` - (Required) A unique name for your Lambda Function.
|
* `function_name` - (Required) A unique name for your Lambda Function.
|
||||||
|
* `dead_letter_config` - (Optional) Nested block to configure the function's *dead letter queue*. See details below.
|
||||||
* `handler` - (Required) The function [entrypoint][3] in your code.
|
* `handler` - (Required) The function [entrypoint][3] in your code.
|
||||||
* `role` - (Required) IAM role attached to the Lambda Function. This governs both who / what can invoke your Lambda Function, as well as what resources our Lambda Function has access to. See [Lambda Permission Model][4] for more details.
|
* `role` - (Required) IAM role attached to the Lambda Function. This governs both who / what can invoke your Lambda Function, as well as what resources our Lambda Function has access to. See [Lambda Permission Model][4] for more details.
|
||||||
* `description` - (Optional) Description of what your Lambda Function does.
|
* `description` - (Optional) Description of what your Lambda Function does.
|
||||||
|
@ -70,6 +71,13 @@ resource "aws_lambda_function" "test_lambda" {
|
||||||
* `source_code_hash` - (Optional) Used to trigger updates. This is only useful in conjunction with `filename`.
|
* `source_code_hash` - (Optional) Used to trigger updates. This is only useful in conjunction with `filename`.
|
||||||
The only useful value is `${base64sha256(file("file.zip"))}`.
|
The only useful value is `${base64sha256(file("file.zip"))}`.
|
||||||
|
|
||||||
|
**dead\_letter\_config** is a child block with a single argument:
|
||||||
|
|
||||||
|
* `target_arn` - (Required) The ARN of an SNS topic or SQS queue to notify when an invocation fails. If this
|
||||||
|
option is used, the function's IAM role must be granted suitable access to write to the target object,
|
||||||
|
which means allowing either the `sns:Publish` or `sqs:SendMessage` action on this ARN, depending on
|
||||||
|
which service is targeted.
|
||||||
|
|
||||||
**vpc\_config** requires the following:
|
**vpc\_config** requires the following:
|
||||||
|
|
||||||
* `subnet_ids` - (Required) A list of subnet IDs associated with the Lambda function.
|
* `subnet_ids` - (Required) A list of subnet IDs associated with the Lambda function.
|
||||||
|
|
Loading…
Reference in New Issue