provider/aws: Add support for X-Ray tracing to aws_lambda_function (#14728)

Fixes: #13801
This commit is contained in:
Paul Stack 2017-05-24 11:37:04 +01:00 committed by GitHub
parent b52bf2c887
commit be58c809b6
3 changed files with 128 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
) )
const awsMutexLambdaKey = `aws_lambda_function` const awsMutexLambdaKey = `aws_lambda_function`
@ -174,6 +175,22 @@ func resourceAwsLambdaFunction() *schema.Resource {
}, },
}, },
"tracing_config": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mode": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{"Active", "PassThrough"}, true),
},
},
},
},
"kms_key_arn": { "kms_key_arn": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -277,6 +294,14 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
} }
} }
if v, ok := d.GetOk("tracing_config"); ok {
tracingConfig := v.([]interface{})
tracing := tracingConfig[0].(map[string]interface{})
params.TracingConfig = &lambda.TracingConfig{
Mode: aws.String(tracing["mode"].(string)),
}
}
if v, ok := d.GetOk("environment"); ok { if v, ok := d.GetOk("environment"); ok {
environments := v.([]interface{}) environments := v.([]interface{})
environment, ok := environments[0].(map[string]interface{}) environment, ok := environments[0].(map[string]interface{})
@ -388,6 +413,14 @@ func resourceAwsLambdaFunctionRead(d *schema.ResourceData, meta interface{}) err
d.Set("dead_letter_config", []interface{}{}) d.Set("dead_letter_config", []interface{}{})
} }
if function.TracingConfig != nil {
d.Set("tracing_config", []interface{}{
map[string]interface{}{
"mode": *function.TracingConfig.Mode,
},
})
}
// 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
@ -549,6 +582,16 @@ func resourceAwsLambdaFunctionUpdate(d *schema.ResourceData, meta interface{}) e
configUpdate = true configUpdate = true
} }
} }
if d.HasChange("tracing_config") {
tracingConfig := d.Get("tracing_config").([]interface{})
if len(tracingConfig) == 1 { // Schema guarantees either 0 or 1
config := tracingConfig[0].(map[string]interface{})
configReq.TracingConfig = &lambda.TracingConfig{
Mode: aws.String(config["mode"].(string)),
}
configUpdate = true
}
}
if d.HasChange("runtime") { if d.HasChange("runtime") {
configReq.Runtime = aws.String(d.Get("runtime").(string)) configReq.Runtime = aws.String(d.Get("runtime").(string))
configUpdate = true configUpdate = true

View File

@ -232,6 +232,39 @@ func TestAccAWSLambdaFunction_DeadLetterConfig(t *testing.T) {
}) })
} }
func TestAccAWSLambdaFunction_tracingConfig(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: testAccAWSLambdaConfigWithTracingConfig(rName, rSt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf),
testAccCheckAwsLambdaFunctionName(&conf, rName),
testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName),
resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "tracing_config.0.mode", "Active"),
),
},
{
Config: testAccAWSLambdaConfigWithTracingConfigUpdated(rName, rSt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf),
testAccCheckAwsLambdaFunctionName(&conf, rName),
testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName),
resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "tracing_config.0.mode", "PassThrough"),
),
},
},
})
}
func TestAccAWSLambdaFunction_VPC(t *testing.T) { func TestAccAWSLambdaFunction_VPC(t *testing.T) {
var conf lambda.GetFunctionOutput var conf lambda.GetFunctionOutput
@ -825,6 +858,15 @@ resource "aws_iam_role_policy" "iam_policy_for_lambda" {
"Resource": [ "Resource": [
"*" "*"
] ]
},
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments"
],
"Resource": [
"*"
]
} }
] ]
} }
@ -1038,6 +1080,40 @@ resource "aws_lambda_function" "lambda_function_test" {
`, rName) `, rName)
} }
func testAccAWSLambdaConfigWithTracingConfig(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"
tracing_config {
mode = "Active"
}
}
`, rName)
}
func testAccAWSLambdaConfigWithTracingConfigUpdated(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"
tracing_config {
mode = "PassThrough"
}
}
`, rName)
}
func testAccAWSLambdaConfigWithDeadLetterConfig(rName, rSt string) string { func testAccAWSLambdaConfigWithDeadLetterConfig(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" {

View File

@ -85,13 +85,21 @@ large files efficiently.
* `source_code_hash` - (Optional) Used to trigger updates. Must be set to a base64-encoded SHA256 hash of the package file specified with either `filename` or `s3_key`. The usual way to set this is `${base64sha256(file("file.zip"))}`, where "file.zip" is the local filename of the lambda function source archive. * `source_code_hash` - (Optional) Used to trigger updates. Must be set to a base64-encoded SHA256 hash of the package file specified with either `filename` or `s3_key`. The usual way to set this is `${base64sha256(file("file.zip"))}`, where "file.zip" is the local filename of the lambda function source archive.
* `tags` - (Optional) A mapping of tags to assign to the object. * `tags` - (Optional) A mapping of tags to assign to the object.
**dead\_letter\_config** is a child block with a single argument: **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 * `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, 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 means allowing either the `sns:Publish` or `sqs:SendMessage` action on this ARN, depending on
which service is targeted. which service is targeted.
**tracing_config** is a child block with a single argument:
* `mode` - (Required) Can be either `PassThrough` or `Active`. If PassThrough, Lambda will only trace
the request from an upstream service if it contains a tracing header with
"sampled=1". If Active, Lambda will respect any tracing header it receives
from an upstream service. If no tracing header is received, Lambda will call
X-Ray for a tracing decision.
**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.