From 7854eeeb4ea7ac71d8f55acc7ef1f1d6d526fcf8 Mon Sep 17 00:00:00 2001 From: Ninir Date: Sun, 30 Oct 2016 18:31:34 +0100 Subject: [PATCH 1/3] provider/aws/lambda: Deprecated nodejs in favor of nodejs4.3 --- .../aws/resource_aws_lambda_function.go | 19 +++++-- .../aws/resource_aws_lambda_function_test.go | 52 +++++++++++-------- .../aws/r/lambda_function.html.markdown | 2 +- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/builtin/providers/aws/resource_aws_lambda_function.go b/builtin/providers/aws/resource_aws_lambda_function.go index f123298e6bd2..a41fdd37bc7f 100644 --- a/builtin/providers/aws/resource_aws_lambda_function.go +++ b/builtin/providers/aws/resource_aws_lambda_function.go @@ -77,10 +77,10 @@ func resourceAwsLambdaFunction() *schema.Resource { Required: true, }, "runtime": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Default: "nodejs", + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRuntime, }, "timeout": { Type: schema.TypeInt, @@ -564,3 +564,14 @@ func validateVPCConfig(v interface{}) (map[string]interface{}, error) { return config, nil } + +func validateRuntime(v interface{}, k string) (ws []string, errors []error) { + runtime := v.(string) + + if runtime == lambda.RuntimeNodejs { + errors = append(errors, fmt.Errorf( + "%s has reached end of life since October 2016 and has been deprecated in favor of %s.", + runtime, lambda.RuntimeNodejs43)) + } + return +} diff --git a/builtin/providers/aws/resource_aws_lambda_function_test.go b/builtin/providers/aws/resource_aws_lambda_function_test.go index 349270d84725..3fd673b3a5f7 100644 --- a/builtin/providers/aws/resource_aws_lambda_function_test.go +++ b/builtin/providers/aws/resource_aws_lambda_function_test.go @@ -611,6 +611,7 @@ resource "aws_lambda_function" "lambda_function_test" { function_name = "%s" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } `, rName) } @@ -710,6 +711,7 @@ resource "aws_lambda_function" "lambda_function_test" { publish = true role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } `, rName) } @@ -721,6 +723,7 @@ resource "aws_lambda_function" "lambda_function_test" { function_name = "%s" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" vpc_config = { subnet_ids = ["${aws_subnet.subnet_for_lambda.id}"] @@ -766,6 +769,7 @@ resource "aws_lambda_function" "lambda_function_s3test" { function_name = "%s" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } `, acctest.RandInt(), rName) } @@ -795,6 +799,7 @@ resource "aws_lambda_function" "lambda_function_local" { function_name = "tf_acc_lambda_name_local" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } ` @@ -832,23 +837,24 @@ resource "aws_lambda_function" "lambda_function_local" { function_name = "tf_acc_lambda_name_local" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } ` const testAccAWSLambdaFunctionConfig_s3_tpl = ` resource "aws_s3_bucket" "artifacts" { - bucket = "%s" - acl = "private" - force_destroy = true - versioning { - enabled = true - } + bucket = "%s" + acl = "private" + force_destroy = true + versioning { + enabled = true + } } resource "aws_s3_bucket_object" "o" { - bucket = "${aws_s3_bucket.artifacts.bucket}" - key = "%s" - source = "%s" - etag = "${md5(file("%s"))}" + bucket = "${aws_s3_bucket.artifacts.bucket}" + key = "%s" + source = "%s" + etag = "${md5(file("%s"))}" } resource "aws_iam_role" "iam_for_lambda" { name = "iam_for_lambda" @@ -869,12 +875,13 @@ resource "aws_iam_role" "iam_for_lambda" { EOF } resource "aws_lambda_function" "lambda_function_s3" { - s3_bucket = "${aws_s3_bucket_object.o.bucket}" - s3_key = "${aws_s3_bucket_object.o.key}" - s3_object_version = "${aws_s3_bucket_object.o.version_id}" + s3_bucket = "${aws_s3_bucket_object.o.bucket}" + s3_key = "${aws_s3_bucket_object.o.key}" + s3_object_version = "${aws_s3_bucket_object.o.version_id}" function_name = "tf_acc_lambda_name_s3" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } ` @@ -885,15 +892,15 @@ func genAWSLambdaFunctionConfig_s3(bucket, key, path string) string { const testAccAWSLambdaFunctionConfig_s3_unversioned_tpl = ` resource "aws_s3_bucket" "artifacts" { - bucket = "%s" - acl = "private" - force_destroy = true + bucket = "%s" + acl = "private" + force_destroy = true } resource "aws_s3_bucket_object" "o" { - bucket = "${aws_s3_bucket.artifacts.bucket}" - key = "%s" - source = "%s" - etag = "${md5(file("%s"))}" + bucket = "${aws_s3_bucket.artifacts.bucket}" + key = "%s" + source = "%s" + etag = "${md5(file("%s"))}" } resource "aws_iam_role" "iam_for_lambda" { name = "iam_for_lambda" @@ -914,11 +921,12 @@ resource "aws_iam_role" "iam_for_lambda" { EOF } resource "aws_lambda_function" "lambda_function_s3" { - s3_bucket = "${aws_s3_bucket_object.o.bucket}" - s3_key = "${aws_s3_bucket_object.o.key}" + s3_bucket = "${aws_s3_bucket_object.o.bucket}" + s3_key = "${aws_s3_bucket_object.o.key}" function_name = "tf_acc_lambda_name_s3_unversioned" role = "${aws_iam_role.iam_for_lambda.arn}" handler = "exports.example" + runtime = "nodejs4.3" } ` diff --git a/website/source/docs/providers/aws/r/lambda_function.html.markdown b/website/source/docs/providers/aws/r/lambda_function.html.markdown index 33a27b332eb5..fe1fff4a1f54 100644 --- a/website/source/docs/providers/aws/r/lambda_function.html.markdown +++ b/website/source/docs/providers/aws/r/lambda_function.html.markdown @@ -54,7 +54,7 @@ resource "aws_lambda_function" "test_lambda" { * `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. * `memory_size` - (Optional) Amount of memory in MB your Lambda Function can use at runtime. Defaults to `128`. See [Limits][5] -* `runtime` - (Optional) Defaults to `nodejs`. See [Runtimes][6] for valid values. +* `runtime` - (Required) See [Runtimes][6] for valid values. * `timeout` - (Optional) The amount of time your Lambda Function has to run in seconds. Defaults to `3`. See [Limits][5] * `publish` - (Optional) Whether to publish creation/change as new Lambda Function Version. Defaults to `false`. * `vpc_config` - (Optional) Provide this to allow your function to access your VPC. Fields documented below. See [Lambda in VPC][7] From 8816784d8ed2f00cb627585c14d839ff9f0be961 Mon Sep 17 00:00:00 2001 From: Ninir Date: Wed, 2 Nov 2016 09:56:57 +0100 Subject: [PATCH 2/3] Removed redundant type declarations in composite literals --- builtin/providers/aws/resource_aws_lambda_function_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_lambda_function_test.go b/builtin/providers/aws/resource_aws_lambda_function_test.go index 3fd673b3a5f7..fef3aab444b4 100644 --- a/builtin/providers/aws/resource_aws_lambda_function_test.go +++ b/builtin/providers/aws/resource_aws_lambda_function_test.go @@ -320,7 +320,7 @@ func TestAccAWSLambdaFunction_s3Update(t *testing.T) { }, // Extra step because of missing ComputedWhen // See https://github.com/hashicorp/terraform/pull/4846 & https://github.com/hashicorp/terraform/pull/5330 - resource.TestStep{ + { Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), Check: resource.ComposeTestCheckFunc( testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3", &conf), From 46a3c4d91d5ca95594cf45ced2479c02f572ecca Mon Sep 17 00:00:00 2001 From: Ninir Date: Thu, 17 Nov 2016 15:12:14 +0100 Subject: [PATCH 3/3] Added validation tests --- .../aws/resource_aws_lambda_function_test.go | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/builtin/providers/aws/resource_aws_lambda_function_test.go b/builtin/providers/aws/resource_aws_lambda_function_test.go index fef3aab444b4..b7f031720d51 100644 --- a/builtin/providers/aws/resource_aws_lambda_function_test.go +++ b/builtin/providers/aws/resource_aws_lambda_function_test.go @@ -381,6 +381,98 @@ func TestAccAWSLambdaFunction_s3Update_unversioned(t *testing.T) { }) } +func TestAccAWSLambdaFunction_runtimeValidation_noRuntime(t *testing.T) { + rName := fmt.Sprintf("tf_test_%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLambdaConfigNoRuntime(rName), + ExpectError: regexp.MustCompile(`\\"runtime\\": required field is not set`), + }, + }, + }) +} + +func TestAccAWSLambdaFunction_runtimeValidation_nodeJs(t *testing.T) { + rName := fmt.Sprintf("tf_test_%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLambdaConfigNodeJsRuntime(rName), + ExpectError: regexp.MustCompile(fmt.Sprintf("%s has reached end of life since October 2016 and has been deprecated in favor of %s", lambda.RuntimeNodejs, lambda.RuntimeNodejs43)), + }, + }, + }) +} + +func TestAccAWSLambdaFunction_runtimeValidation_nodeJs43(t *testing.T) { + var conf lambda.GetFunctionOutput + rName := fmt.Sprintf("tf_test_%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLambdaConfigNodeJs43Runtime(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), + resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "runtime", lambda.RuntimeNodejs43), + ), + }, + }, + }) +} + +func TestAccAWSLambdaFunction_runtimeValidation_python27(t *testing.T) { + var conf lambda.GetFunctionOutput + rName := fmt.Sprintf("tf_test_%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLambdaConfigPython27Runtime(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), + resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "runtime", lambda.RuntimePython27), + ), + }, + }, + }) +} + +func TestAccAWSLambdaFunction_runtimeValidation_java8(t *testing.T) { + var conf lambda.GetFunctionOutput + rName := fmt.Sprintf("tf_test_%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLambdaFunctionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLambdaConfigJava8Runtime(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), + resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "runtime", lambda.RuntimeJava8), + ), + }, + }, + }) +} + func testAccCheckLambdaFunctionDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).lambdaconn @@ -774,6 +866,65 @@ resource "aws_lambda_function" "lambda_function_s3test" { `, acctest.RandInt(), rName) } +func testAccAWSLambdaConfigNoRuntime(rName string) string { + return fmt.Sprintf(baseAccAWSLambdaConfig+` +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" +} +`, rName) +} + +func testAccAWSLambdaConfigNodeJsRuntime(rName string) string { + return fmt.Sprintf(baseAccAWSLambdaConfig+` +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 = "nodejs" +} +`, rName) +} + +func testAccAWSLambdaConfigNodeJs43Runtime(rName string) string { + return fmt.Sprintf(baseAccAWSLambdaConfig+` +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" +} +`, rName) +} + +func testAccAWSLambdaConfigPython27Runtime(rName string) string { + return fmt.Sprintf(baseAccAWSLambdaConfig+` +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 = "python2.7" +} +`, rName) +} + +func testAccAWSLambdaConfigJava8Runtime(rName string) string { + return fmt.Sprintf(baseAccAWSLambdaConfig+` +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 = "java8" +} +`, rName) +} + const testAccAWSLambdaFunctionConfig_local_tpl = ` resource "aws_iam_role" "iam_for_lambda" { name = "iam_for_lambda"