github.com/ggriffiths/terraform@v0.9.0-beta1.0.20170222213024-79c4935604cb/builtin/providers/aws/resource_aws_lambda_function_test.go (about) 1 package aws 2 3 import ( 4 "archive/zip" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "regexp" 10 "strings" 11 "testing" 12 13 "github.com/aws/aws-sdk-go/aws" 14 "github.com/aws/aws-sdk-go/service/lambda" 15 "github.com/hashicorp/terraform/helper/acctest" 16 "github.com/hashicorp/terraform/helper/resource" 17 "github.com/hashicorp/terraform/terraform" 18 ) 19 20 func TestAccAWSLambdaFunction_basic(t *testing.T) { 21 var conf lambda.GetFunctionOutput 22 23 rSt := acctest.RandString(5) 24 rName := fmt.Sprintf("tf_test_%s", rSt) 25 26 resource.Test(t, resource.TestCase{ 27 PreCheck: func() { testAccPreCheck(t) }, 28 Providers: testAccProviders, 29 CheckDestroy: testAccCheckLambdaFunctionDestroy, 30 Steps: []resource.TestStep{ 31 { 32 Config: testAccAWSLambdaConfigBasic(rName, rSt), 33 Check: resource.ComposeTestCheckFunc( 34 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 35 testAccCheckAwsLambdaFunctionName(&conf, rName), 36 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 37 ), 38 }, 39 }, 40 }) 41 } 42 43 func TestAccAWSLambdaFunction_expectFilenameAndS3Attributes(t *testing.T) { 44 rSt := acctest.RandString(5) 45 rName := fmt.Sprintf("tf_test_%s", rSt) 46 47 resource.Test(t, resource.TestCase{ 48 PreCheck: func() { testAccPreCheck(t) }, 49 Providers: testAccProviders, 50 CheckDestroy: testAccCheckLambdaFunctionDestroy, 51 Steps: []resource.TestStep{ 52 { 53 Config: testAccAWSLambdaConfigWithoutFilenameAndS3Attributes(rName, rSt), 54 ExpectError: regexp.MustCompile(`filename or s3_\* attributes must be set`), 55 }, 56 }, 57 }) 58 } 59 60 func TestAccAWSLambdaFunction_envVariables(t *testing.T) { 61 var conf lambda.GetFunctionOutput 62 63 rSt := acctest.RandString(5) 64 rName := fmt.Sprintf("tf_test_%s", rSt) 65 66 resource.Test(t, resource.TestCase{ 67 PreCheck: func() { testAccPreCheck(t) }, 68 Providers: testAccProviders, 69 CheckDestroy: testAccCheckLambdaFunctionDestroy, 70 Steps: []resource.TestStep{ 71 { 72 Config: testAccAWSLambdaConfigBasic(rName, rSt), 73 Check: resource.ComposeTestCheckFunc( 74 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 75 testAccCheckAwsLambdaFunctionName(&conf, rName), 76 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 77 resource.TestCheckNoResourceAttr("aws_lambda_function.lambda_function_test", "environment"), 78 ), 79 }, 80 { 81 Config: testAccAWSLambdaConfigEnvVariables(rName, rSt), 82 Check: resource.ComposeTestCheckFunc( 83 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 84 testAccCheckAwsLambdaFunctionName(&conf, rName), 85 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 86 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "environment.0.variables.foo", "bar"), 87 ), 88 }, 89 { 90 Config: testAccAWSLambdaConfigEnvVariablesModified(rName, rSt), 91 Check: resource.ComposeTestCheckFunc( 92 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 93 testAccCheckAwsLambdaFunctionName(&conf, rName), 94 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 95 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "environment.0.variables.foo", "baz"), 96 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "environment.0.variables.foo1", "bar1"), 97 ), 98 }, 99 { 100 Config: testAccAWSLambdaConfigEnvVariablesModifiedWithoutEnvironment(rName, rSt), 101 Check: resource.ComposeTestCheckFunc( 102 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 103 testAccCheckAwsLambdaFunctionName(&conf, rName), 104 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 105 resource.TestCheckNoResourceAttr("aws_lambda_function.lambda_function_test", "environment"), 106 ), 107 }, 108 }, 109 }) 110 } 111 112 func TestAccAWSLambdaFunction_encryptedEnvVariables(t *testing.T) { 113 var conf lambda.GetFunctionOutput 114 115 rSt := acctest.RandString(5) 116 rName := fmt.Sprintf("tf_test_%s", rSt) 117 keyRegex := regexp.MustCompile("^arn:aws:kms:") 118 119 resource.Test(t, resource.TestCase{ 120 PreCheck: func() { testAccPreCheck(t) }, 121 Providers: testAccProviders, 122 CheckDestroy: testAccCheckLambdaFunctionDestroy, 123 Steps: []resource.TestStep{ 124 { 125 Config: testAccAWSLambdaConfigEncryptedEnvVariables(rName, rSt), 126 Check: resource.ComposeTestCheckFunc( 127 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 128 testAccCheckAwsLambdaFunctionName(&conf, rName), 129 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 130 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "environment.0.variables.foo", "bar"), 131 resource.TestMatchResourceAttr("aws_lambda_function.lambda_function_test", "kms_key_arn", keyRegex), 132 ), 133 }, 134 { 135 Config: testAccAWSLambdaConfigEncryptedEnvVariablesModified(rName, rSt), 136 Check: resource.ComposeTestCheckFunc( 137 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 138 testAccCheckAwsLambdaFunctionName(&conf, rName), 139 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 140 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "environment.0.variables.foo", "bar"), 141 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "kms_key_arn", ""), 142 ), 143 }, 144 }, 145 }) 146 } 147 148 func TestAccAWSLambdaFunction_versioned(t *testing.T) { 149 var conf lambda.GetFunctionOutput 150 151 rSt := acctest.RandString(5) 152 rName := fmt.Sprintf("tf_test_%s", rSt) 153 154 resource.Test(t, resource.TestCase{ 155 PreCheck: func() { testAccPreCheck(t) }, 156 Providers: testAccProviders, 157 CheckDestroy: testAccCheckLambdaFunctionDestroy, 158 Steps: []resource.TestStep{ 159 { 160 Config: testAccAWSLambdaConfigVersioned(rName, rSt), 161 Check: resource.ComposeTestCheckFunc( 162 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 163 testAccCheckAwsLambdaFunctionName(&conf, rName), 164 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 165 resource.TestMatchResourceAttr("aws_lambda_function.lambda_function_test", "version", 166 regexp.MustCompile("^[0-9]+$")), 167 resource.TestMatchResourceAttr("aws_lambda_function.lambda_function_test", "qualified_arn", 168 regexp.MustCompile(":"+rName+":[0-9]+$")), 169 ), 170 }, 171 }, 172 }) 173 } 174 175 func TestAccAWSLambdaFunction_VPC(t *testing.T) { 176 var conf lambda.GetFunctionOutput 177 178 rSt := acctest.RandString(5) 179 rName := fmt.Sprintf("tf_test_%s", rSt) 180 181 resource.Test(t, resource.TestCase{ 182 PreCheck: func() { testAccPreCheck(t) }, 183 Providers: testAccProviders, 184 CheckDestroy: testAccCheckLambdaFunctionDestroy, 185 Steps: []resource.TestStep{ 186 { 187 Config: testAccAWSLambdaConfigWithVPC(rName, rSt), 188 Check: resource.ComposeTestCheckFunc( 189 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 190 testAccCheckAwsLambdaFunctionName(&conf, rName), 191 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 192 testAccCheckAWSLambdaFunctionVersion(&conf, "$LATEST"), 193 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "vpc_config.#", "1"), 194 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "vpc_config.0.subnet_ids.#", "1"), 195 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "vpc_config.0.security_group_ids.#", "1"), 196 resource.TestMatchResourceAttr("aws_lambda_function.lambda_function_test", "vpc_config.0.vpc_id", regexp.MustCompile("^vpc-")), 197 ), 198 }, 199 }, 200 }) 201 } 202 203 func TestAccAWSLambdaFunction_s3(t *testing.T) { 204 var conf lambda.GetFunctionOutput 205 rSt := acctest.RandString(5) 206 rName := fmt.Sprintf("tf_test_%s", rSt) 207 208 resource.Test(t, resource.TestCase{ 209 PreCheck: func() { testAccPreCheck(t) }, 210 Providers: testAccProviders, 211 CheckDestroy: testAccCheckLambdaFunctionDestroy, 212 Steps: []resource.TestStep{ 213 { 214 Config: testAccAWSLambdaConfigS3(rName, rSt), 215 Check: resource.ComposeTestCheckFunc( 216 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3test", rName, &conf), 217 testAccCheckAwsLambdaFunctionName(&conf, rName), 218 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, ":"+rName), 219 testAccCheckAWSLambdaFunctionVersion(&conf, "$LATEST"), 220 ), 221 }, 222 }, 223 }) 224 } 225 226 func TestAccAWSLambdaFunction_localUpdate(t *testing.T) { 227 var conf lambda.GetFunctionOutput 228 229 path, zipFile, err := createTempFile("lambda_localUpdate") 230 if err != nil { 231 t.Fatal(err) 232 } 233 defer os.Remove(path) 234 235 resource.Test(t, resource.TestCase{ 236 PreCheck: func() { testAccPreCheck(t) }, 237 Providers: testAccProviders, 238 CheckDestroy: testAccCheckLambdaFunctionDestroy, 239 Steps: []resource.TestStep{ 240 { 241 PreConfig: func() { 242 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func.js": "lambda.js"}, zipFile) 243 }, 244 Config: genAWSLambdaFunctionConfig_local(path), 245 Check: resource.ComposeTestCheckFunc( 246 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_local", "tf_acc_lambda_name_local", &conf), 247 testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_local"), 248 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_local"), 249 testAccCheckAwsLambdaSourceCodeHash(&conf, "8DPiX+G1l2LQ8hjBkwRchQFf1TSCEvPrYGRKlM9UoyY="), 250 ), 251 }, 252 { 253 PreConfig: func() { 254 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func_modified.js": "lambda.js"}, zipFile) 255 }, 256 Config: genAWSLambdaFunctionConfig_local(path), 257 Check: resource.ComposeTestCheckFunc( 258 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_local", "tf_acc_lambda_name_local", &conf), 259 testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_local"), 260 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_local"), 261 testAccCheckAwsLambdaSourceCodeHash(&conf, "0tdaP9H9hsk9c2CycSwOG/sa/x5JyAmSYunA/ce99Pg="), 262 ), 263 }, 264 }, 265 }) 266 } 267 268 func TestAccAWSLambdaFunction_localUpdate_nameOnly(t *testing.T) { 269 var conf lambda.GetFunctionOutput 270 271 rName := fmt.Sprintf("tf_test_iam_%d", acctest.RandInt()) 272 273 path, zipFile, err := createTempFile("lambda_localUpdate") 274 if err != nil { 275 t.Fatal(err) 276 } 277 defer os.Remove(path) 278 279 updatedPath, updatedZipFile, err := createTempFile("lambda_localUpdate_name_change") 280 if err != nil { 281 t.Fatal(err) 282 } 283 defer os.Remove(updatedPath) 284 285 resource.Test(t, resource.TestCase{ 286 PreCheck: func() { testAccPreCheck(t) }, 287 Providers: testAccProviders, 288 CheckDestroy: testAccCheckLambdaFunctionDestroy, 289 Steps: []resource.TestStep{ 290 { 291 PreConfig: func() { 292 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func.js": "lambda.js"}, zipFile) 293 }, 294 Config: genAWSLambdaFunctionConfig_local_name_only(path, rName), 295 Check: resource.ComposeTestCheckFunc( 296 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_local", rName, &conf), 297 testAccCheckAwsLambdaFunctionName(&conf, rName), 298 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, rName), 299 testAccCheckAwsLambdaSourceCodeHash(&conf, "8DPiX+G1l2LQ8hjBkwRchQFf1TSCEvPrYGRKlM9UoyY="), 300 ), 301 }, 302 { 303 PreConfig: func() { 304 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func_modified.js": "lambda.js"}, updatedZipFile) 305 }, 306 Config: genAWSLambdaFunctionConfig_local_name_only(updatedPath, rName), 307 Check: resource.ComposeTestCheckFunc( 308 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_local", rName, &conf), 309 testAccCheckAwsLambdaFunctionName(&conf, rName), 310 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, rName), 311 testAccCheckAwsLambdaSourceCodeHash(&conf, "0tdaP9H9hsk9c2CycSwOG/sa/x5JyAmSYunA/ce99Pg="), 312 ), 313 }, 314 }, 315 }) 316 } 317 318 func TestAccAWSLambdaFunction_s3Update(t *testing.T) { 319 var conf lambda.GetFunctionOutput 320 321 path, zipFile, err := createTempFile("lambda_s3Update") 322 if err != nil { 323 t.Fatal(err) 324 } 325 defer os.Remove(path) 326 327 bucketName := fmt.Sprintf("tf-acc-lambda-s3-deployments-%d", randomInteger) 328 key := "lambda-func.zip" 329 330 resource.Test(t, resource.TestCase{ 331 PreCheck: func() { testAccPreCheck(t) }, 332 Providers: testAccProviders, 333 CheckDestroy: testAccCheckLambdaFunctionDestroy, 334 Steps: []resource.TestStep{ 335 { 336 PreConfig: func() { 337 // Upload 1st version 338 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func.js": "lambda.js"}, zipFile) 339 }, 340 Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), 341 Check: resource.ComposeTestCheckFunc( 342 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3", &conf), 343 testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_s3"), 344 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_s3"), 345 testAccCheckAwsLambdaSourceCodeHash(&conf, "8DPiX+G1l2LQ8hjBkwRchQFf1TSCEvPrYGRKlM9UoyY="), 346 ), 347 }, 348 { 349 ExpectNonEmptyPlan: true, 350 PreConfig: func() { 351 // Upload 2nd version 352 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func_modified.js": "lambda.js"}, zipFile) 353 }, 354 Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), 355 }, 356 // Extra step because of missing ComputedWhen 357 // See https://github.com/hashicorp/terraform/pull/4846 & https://github.com/hashicorp/terraform/pull/5330 358 { 359 Config: genAWSLambdaFunctionConfig_s3(bucketName, key, path), 360 Check: resource.ComposeTestCheckFunc( 361 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3", &conf), 362 testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_s3"), 363 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_s3"), 364 testAccCheckAwsLambdaSourceCodeHash(&conf, "0tdaP9H9hsk9c2CycSwOG/sa/x5JyAmSYunA/ce99Pg="), 365 ), 366 }, 367 }, 368 }) 369 } 370 371 func TestAccAWSLambdaFunction_s3Update_unversioned(t *testing.T) { 372 var conf lambda.GetFunctionOutput 373 374 rName := fmt.Sprintf("tf_iam_lambda_%d", acctest.RandInt()) 375 376 path, zipFile, err := createTempFile("lambda_s3Update") 377 if err != nil { 378 t.Fatal(err) 379 } 380 defer os.Remove(path) 381 382 bucketName := fmt.Sprintf("tf-acc-lambda-s3-deployments-%d", randomInteger) 383 key := "lambda-func.zip" 384 key2 := "lambda-func-modified.zip" 385 386 resource.Test(t, resource.TestCase{ 387 PreCheck: func() { testAccPreCheck(t) }, 388 Providers: testAccProviders, 389 CheckDestroy: testAccCheckLambdaFunctionDestroy, 390 Steps: []resource.TestStep{ 391 { 392 PreConfig: func() { 393 // Upload 1st version 394 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func.js": "lambda.js"}, zipFile) 395 }, 396 Config: testAccAWSLambdaFunctionConfig_s3_unversioned_tpl(rName, bucketName, key, path), 397 Check: resource.ComposeTestCheckFunc( 398 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3_unversioned", &conf), 399 testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_s3_unversioned"), 400 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_s3_unversioned"), 401 testAccCheckAwsLambdaSourceCodeHash(&conf, "8DPiX+G1l2LQ8hjBkwRchQFf1TSCEvPrYGRKlM9UoyY="), 402 ), 403 }, 404 { 405 PreConfig: func() { 406 // Upload 2nd version 407 testAccCreateZipFromFiles(map[string]string{"test-fixtures/lambda_func_modified.js": "lambda.js"}, zipFile) 408 }, 409 Config: testAccAWSLambdaFunctionConfig_s3_unversioned_tpl(rName, bucketName, key2, path), 410 Check: resource.ComposeTestCheckFunc( 411 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_s3", "tf_acc_lambda_name_s3_unversioned", &conf), 412 testAccCheckAwsLambdaFunctionName(&conf, "tf_acc_lambda_name_s3_unversioned"), 413 testAccCheckAwsLambdaFunctionArnHasSuffix(&conf, "tf_acc_lambda_name_s3_unversioned"), 414 testAccCheckAwsLambdaSourceCodeHash(&conf, "0tdaP9H9hsk9c2CycSwOG/sa/x5JyAmSYunA/ce99Pg="), 415 ), 416 }, 417 }, 418 }) 419 } 420 421 func TestAccAWSLambdaFunction_runtimeValidation_noRuntime(t *testing.T) { 422 rSt := acctest.RandString(5) 423 rName := fmt.Sprintf("tf_test_%s", rSt) 424 425 resource.Test(t, resource.TestCase{ 426 PreCheck: func() { testAccPreCheck(t) }, 427 Providers: testAccProviders, 428 CheckDestroy: testAccCheckLambdaFunctionDestroy, 429 Steps: []resource.TestStep{ 430 { 431 Config: testAccAWSLambdaConfigNoRuntime(rName, rSt), 432 ExpectError: regexp.MustCompile(`\\"runtime\\": required field is not set`), 433 }, 434 }, 435 }) 436 } 437 438 func TestAccAWSLambdaFunction_runtimeValidation_nodeJs(t *testing.T) { 439 rSt := acctest.RandString(5) 440 rName := fmt.Sprintf("tf_test_%s", rSt) 441 442 resource.Test(t, resource.TestCase{ 443 PreCheck: func() { testAccPreCheck(t) }, 444 Providers: testAccProviders, 445 CheckDestroy: testAccCheckLambdaFunctionDestroy, 446 Steps: []resource.TestStep{ 447 { 448 Config: testAccAWSLambdaConfigNodeJsRuntime(rName, rSt), 449 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)), 450 }, 451 }, 452 }) 453 } 454 455 func TestAccAWSLambdaFunction_runtimeValidation_nodeJs43(t *testing.T) { 456 var conf lambda.GetFunctionOutput 457 rSt := acctest.RandString(5) 458 rName := fmt.Sprintf("tf_test_%s", rSt) 459 460 resource.Test(t, resource.TestCase{ 461 PreCheck: func() { testAccPreCheck(t) }, 462 Providers: testAccProviders, 463 CheckDestroy: testAccCheckLambdaFunctionDestroy, 464 Steps: []resource.TestStep{ 465 { 466 Config: testAccAWSLambdaConfigNodeJs43Runtime(rName, rSt), 467 Check: resource.ComposeTestCheckFunc( 468 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 469 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "runtime", lambda.RuntimeNodejs43), 470 ), 471 }, 472 }, 473 }) 474 } 475 476 func TestAccAWSLambdaFunction_runtimeValidation_python27(t *testing.T) { 477 var conf lambda.GetFunctionOutput 478 rSt := acctest.RandString(5) 479 rName := fmt.Sprintf("tf_test_%s", rSt) 480 481 resource.Test(t, resource.TestCase{ 482 PreCheck: func() { testAccPreCheck(t) }, 483 Providers: testAccProviders, 484 CheckDestroy: testAccCheckLambdaFunctionDestroy, 485 Steps: []resource.TestStep{ 486 { 487 Config: testAccAWSLambdaConfigPython27Runtime(rName, rSt), 488 Check: resource.ComposeTestCheckFunc( 489 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 490 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "runtime", lambda.RuntimePython27), 491 ), 492 }, 493 }, 494 }) 495 } 496 497 func TestAccAWSLambdaFunction_runtimeValidation_java8(t *testing.T) { 498 var conf lambda.GetFunctionOutput 499 rSt := acctest.RandString(5) 500 rName := fmt.Sprintf("tf_test_%s", rSt) 501 502 resource.Test(t, resource.TestCase{ 503 PreCheck: func() { testAccPreCheck(t) }, 504 Providers: testAccProviders, 505 CheckDestroy: testAccCheckLambdaFunctionDestroy, 506 Steps: []resource.TestStep{ 507 { 508 Config: testAccAWSLambdaConfigJava8Runtime(rName, rSt), 509 Check: resource.ComposeTestCheckFunc( 510 testAccCheckAwsLambdaFunctionExists("aws_lambda_function.lambda_function_test", rName, &conf), 511 resource.TestCheckResourceAttr("aws_lambda_function.lambda_function_test", "runtime", lambda.RuntimeJava8), 512 ), 513 }, 514 }, 515 }) 516 } 517 518 func testAccCheckLambdaFunctionDestroy(s *terraform.State) error { 519 conn := testAccProvider.Meta().(*AWSClient).lambdaconn 520 521 for _, rs := range s.RootModule().Resources { 522 if rs.Type != "aws_lambda_function" { 523 continue 524 } 525 526 _, err := conn.GetFunction(&lambda.GetFunctionInput{ 527 FunctionName: aws.String(rs.Primary.ID), 528 }) 529 530 if err == nil { 531 return fmt.Errorf("Lambda Function still exists") 532 } 533 534 } 535 536 return nil 537 538 } 539 540 func testAccCheckAwsLambdaFunctionExists(res, funcName string, function *lambda.GetFunctionOutput) resource.TestCheckFunc { 541 // Wait for IAM role 542 return func(s *terraform.State) error { 543 rs, ok := s.RootModule().Resources[res] 544 if !ok { 545 return fmt.Errorf("Lambda function not found: %s", res) 546 } 547 548 if rs.Primary.ID == "" { 549 return fmt.Errorf("Lambda function ID not set") 550 } 551 552 conn := testAccProvider.Meta().(*AWSClient).lambdaconn 553 554 params := &lambda.GetFunctionInput{ 555 FunctionName: aws.String(funcName), 556 } 557 558 getFunction, err := conn.GetFunction(params) 559 if err != nil { 560 return err 561 } 562 563 *function = *getFunction 564 565 return nil 566 } 567 } 568 569 func testAccCheckAwsLambdaFunctionName(function *lambda.GetFunctionOutput, expectedName string) resource.TestCheckFunc { 570 return func(s *terraform.State) error { 571 c := function.Configuration 572 if *c.FunctionName != expectedName { 573 return fmt.Errorf("Expected function name %s, got %s", expectedName, *c.FunctionName) 574 } 575 576 return nil 577 } 578 } 579 580 func testAccCheckAWSLambdaFunctionVersion(function *lambda.GetFunctionOutput, expectedVersion string) resource.TestCheckFunc { 581 return func(s *terraform.State) error { 582 c := function.Configuration 583 if *c.Version != expectedVersion { 584 return fmt.Errorf("Expected version %s, got %s", expectedVersion, *c.Version) 585 } 586 return nil 587 } 588 } 589 590 func testAccCheckAwsLambdaFunctionArnHasSuffix(function *lambda.GetFunctionOutput, arnSuffix string) resource.TestCheckFunc { 591 return func(s *terraform.State) error { 592 c := function.Configuration 593 if !strings.HasSuffix(*c.FunctionArn, arnSuffix) { 594 return fmt.Errorf("Expected function ARN %s to have suffix %s", *c.FunctionArn, arnSuffix) 595 } 596 597 return nil 598 } 599 } 600 601 func testAccCheckAwsLambdaSourceCodeHash(function *lambda.GetFunctionOutput, expectedHash string) resource.TestCheckFunc { 602 return func(s *terraform.State) error { 603 c := function.Configuration 604 if *c.CodeSha256 != expectedHash { 605 return fmt.Errorf("Expected code hash %s, got %s", expectedHash, *c.CodeSha256) 606 } 607 608 return nil 609 } 610 } 611 612 func testAccCreateZipFromFiles(files map[string]string, zipFile *os.File) error { 613 zipFile.Truncate(0) 614 zipFile.Seek(0, 0) 615 616 w := zip.NewWriter(zipFile) 617 618 for source, destination := range files { 619 f, err := w.Create(destination) 620 if err != nil { 621 return err 622 } 623 624 fileContent, err := ioutil.ReadFile(source) 625 if err != nil { 626 return err 627 } 628 629 _, err = f.Write(fileContent) 630 if err != nil { 631 return err 632 } 633 } 634 635 err := w.Close() 636 if err != nil { 637 return err 638 } 639 640 return w.Flush() 641 } 642 643 func createTempFile(prefix string) (string, *os.File, error) { 644 f, err := ioutil.TempFile(os.TempDir(), prefix) 645 if err != nil { 646 return "", nil, err 647 } 648 649 pathToFile, err := filepath.Abs(f.Name()) 650 if err != nil { 651 return "", nil, err 652 } 653 return pathToFile, f, nil 654 } 655 656 func baseAccAWSLambdaConfig(rst string) string { 657 return fmt.Sprintf(` 658 resource "aws_iam_role_policy" "iam_policy_for_lambda" { 659 name = "iam_policy_for_lambda_%s" 660 role = "${aws_iam_role.iam_for_lambda.id}" 661 policy = <<EOF 662 { 663 "Version": "2012-10-17", 664 "Statement": [ 665 { 666 "Effect": "Allow", 667 "Action": [ 668 "logs:CreateLogGroup", 669 "logs:CreateLogStream", 670 "logs:PutLogEvents" 671 ], 672 "Resource": "arn:aws:logs:*:*:*" 673 }, 674 { 675 "Effect": "Allow", 676 "Action": [ 677 "ec2:CreateNetworkInterface", 678 "ec2:DescribeNetworkInterfaces", 679 "ec2:DeleteNetworkInterface" 680 ], 681 "Resource": [ 682 "*" 683 ] 684 } 685 ] 686 } 687 EOF 688 } 689 690 resource "aws_iam_role" "iam_for_lambda" { 691 name = "iam_for_lambda_%s" 692 assume_role_policy = <<EOF 693 { 694 "Version": "2012-10-17", 695 "Statement": [ 696 { 697 "Action": "sts:AssumeRole", 698 "Principal": { 699 "Service": "lambda.amazonaws.com" 700 }, 701 "Effect": "Allow", 702 "Sid": "" 703 } 704 ] 705 } 706 EOF 707 } 708 709 resource "aws_vpc" "vpc_for_lambda" { 710 cidr_block = "10.0.0.0/16" 711 } 712 713 resource "aws_subnet" "subnet_for_lambda" { 714 vpc_id = "${aws_vpc.vpc_for_lambda.id}" 715 cidr_block = "10.0.1.0/24" 716 717 tags { 718 Name = "lambda" 719 } 720 } 721 722 resource "aws_security_group" "sg_for_lambda" { 723 name = "sg_for_lambda_%s" 724 description = "Allow all inbound traffic for lambda test" 725 vpc_id = "${aws_vpc.vpc_for_lambda.id}" 726 727 ingress { 728 from_port = 0 729 to_port = 0 730 protocol = "-1" 731 cidr_blocks = ["0.0.0.0/0"] 732 } 733 734 egress { 735 from_port = 0 736 to_port = 0 737 protocol = "-1" 738 cidr_blocks = ["0.0.0.0/0"] 739 } 740 }`, rst, rst, rst) 741 } 742 743 func testAccAWSLambdaConfigBasic(rName, rSt string) string { 744 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 745 resource "aws_lambda_function" "lambda_function_test" { 746 filename = "test-fixtures/lambdatest.zip" 747 function_name = "%s" 748 role = "${aws_iam_role.iam_for_lambda.arn}" 749 handler = "exports.example" 750 runtime = "nodejs4.3" 751 } 752 `, rName) 753 } 754 755 func testAccAWSLambdaConfigWithoutFilenameAndS3Attributes(rName, rSt string) string { 756 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 757 resource "aws_lambda_function" "lambda_function_test" { 758 function_name = "%s" 759 role = "${aws_iam_role.iam_for_lambda.arn}" 760 handler = "exports.example" 761 runtime = "nodejs4.3" 762 } 763 `, rName) 764 } 765 766 func testAccAWSLambdaConfigEnvVariables(rName, rSt string) string { 767 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 768 resource "aws_lambda_function" "lambda_function_test" { 769 filename = "test-fixtures/lambdatest.zip" 770 function_name = "%s" 771 role = "${aws_iam_role.iam_for_lambda.arn}" 772 handler = "exports.example" 773 runtime = "nodejs4.3" 774 environment { 775 variables = { 776 foo = "bar" 777 } 778 } 779 } 780 `, rName) 781 } 782 783 func testAccAWSLambdaConfigEnvVariablesModified(rName, rSt string) string { 784 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 785 resource "aws_lambda_function" "lambda_function_test" { 786 filename = "test-fixtures/lambdatest.zip" 787 function_name = "%s" 788 role = "${aws_iam_role.iam_for_lambda.arn}" 789 handler = "exports.example" 790 runtime = "nodejs4.3" 791 environment { 792 variables = { 793 foo = "baz" 794 foo1 = "bar1" 795 } 796 } 797 } 798 `, rName) 799 } 800 801 func testAccAWSLambdaConfigEnvVariablesModifiedWithoutEnvironment(rName, rSt string) string { 802 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 803 resource "aws_lambda_function" "lambda_function_test" { 804 filename = "test-fixtures/lambdatest.zip" 805 function_name = "%s" 806 role = "${aws_iam_role.iam_for_lambda.arn}" 807 handler = "exports.example" 808 runtime = "nodejs4.3" 809 } 810 `, rName) 811 } 812 813 func testAccAWSLambdaConfigEncryptedEnvVariables(rName, rSt string) string { 814 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 815 resource "aws_kms_key" "foo" { 816 description = "Terraform acc test %s" 817 policy = <<POLICY 818 { 819 "Version": "2012-10-17", 820 "Id": "kms-tf-1", 821 "Statement": [ 822 { 823 "Sid": "Enable IAM User Permissions", 824 "Effect": "Allow", 825 "Principal": { 826 "AWS": "*" 827 }, 828 "Action": "kms:*", 829 "Resource": "*" 830 } 831 ] 832 } 833 POLICY 834 } 835 836 resource "aws_lambda_function" "lambda_function_test" { 837 filename = "test-fixtures/lambdatest.zip" 838 function_name = "%s" 839 role = "${aws_iam_role.iam_for_lambda.arn}" 840 handler = "exports.example" 841 kms_key_arn = "${aws_kms_key.foo.arn}" 842 runtime = "nodejs4.3" 843 environment { 844 variables = { 845 foo = "bar" 846 } 847 } 848 } 849 `, rName, rName) 850 } 851 852 func testAccAWSLambdaConfigEncryptedEnvVariablesModified(rName, rSt string) string { 853 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 854 resource "aws_lambda_function" "lambda_function_test" { 855 filename = "test-fixtures/lambdatest.zip" 856 function_name = "%s" 857 role = "${aws_iam_role.iam_for_lambda.arn}" 858 handler = "exports.example" 859 runtime = "nodejs4.3" 860 environment { 861 variables = { 862 foo = "bar" 863 } 864 } 865 } 866 `, rName) 867 } 868 869 func testAccAWSLambdaConfigVersioned(rName, rSt string) string { 870 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 871 resource "aws_lambda_function" "lambda_function_test" { 872 filename = "test-fixtures/lambdatest.zip" 873 function_name = "%s" 874 publish = true 875 role = "${aws_iam_role.iam_for_lambda.arn}" 876 handler = "exports.example" 877 runtime = "nodejs4.3" 878 } 879 `, rName) 880 } 881 882 func testAccAWSLambdaConfigWithVPC(rName, rSt string) string { 883 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 884 resource "aws_lambda_function" "lambda_function_test" { 885 filename = "test-fixtures/lambdatest.zip" 886 function_name = "%s" 887 role = "${aws_iam_role.iam_for_lambda.arn}" 888 handler = "exports.example" 889 runtime = "nodejs4.3" 890 891 vpc_config = { 892 subnet_ids = ["${aws_subnet.subnet_for_lambda.id}"] 893 security_group_ids = ["${aws_security_group.sg_for_lambda.id}"] 894 } 895 }`, rName) 896 } 897 898 func testAccAWSLambdaConfigS3(rName, rSt string) string { 899 return fmt.Sprintf(` 900 resource "aws_s3_bucket" "lambda_bucket" { 901 bucket = "tf-test-bucket-%d" 902 } 903 904 resource "aws_s3_bucket_object" "lambda_code" { 905 bucket = "${aws_s3_bucket.lambda_bucket.id}" 906 key = "lambdatest.zip" 907 source = "test-fixtures/lambdatest.zip" 908 } 909 910 resource "aws_iam_role" "iam_for_lambda" { 911 name = "iam_for_lambda_%s" 912 assume_role_policy = <<EOF 913 { 914 "Version": "2012-10-17", 915 "Statement": [ 916 { 917 "Action": "sts:AssumeRole", 918 "Principal": { 919 "Service": "lambda.amazonaws.com" 920 }, 921 "Effect": "Allow", 922 "Sid": "" 923 } 924 ] 925 } 926 EOF 927 } 928 929 resource "aws_lambda_function" "lambda_function_s3test" { 930 s3_bucket = "${aws_s3_bucket.lambda_bucket.id}" 931 s3_key = "${aws_s3_bucket_object.lambda_code.id}" 932 function_name = "%s" 933 role = "${aws_iam_role.iam_for_lambda.arn}" 934 handler = "exports.example" 935 runtime = "nodejs4.3" 936 } 937 `, acctest.RandInt(), rSt, rName) 938 } 939 940 func testAccAWSLambdaConfigNoRuntime(rName, rSt string) string { 941 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 942 resource "aws_lambda_function" "lambda_function_test" { 943 filename = "test-fixtures/lambdatest.zip" 944 function_name = "%s" 945 role = "${aws_iam_role.iam_for_lambda.arn}" 946 handler = "exports.example" 947 runtime = "nodejs4.3" 948 } 949 `, rName) 950 } 951 952 func testAccAWSLambdaConfigNodeJsRuntime(rName, rSt string) string { 953 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 954 resource "aws_lambda_function" "lambda_function_test" { 955 filename = "test-fixtures/lambdatest.zip" 956 function_name = "%s" 957 role = "${aws_iam_role.iam_for_lambda.arn}" 958 handler = "exports.example" 959 runtime = "nodejs4.3" 960 } 961 `, rName) 962 } 963 964 func testAccAWSLambdaConfigNodeJs43Runtime(rName, rSt string) string { 965 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 966 resource "aws_lambda_function" "lambda_function_test" { 967 filename = "test-fixtures/lambdatest.zip" 968 function_name = "%s" 969 role = "${aws_iam_role.iam_for_lambda.arn}" 970 handler = "exports.example" 971 runtime = "nodejs4.3" 972 } 973 `, rName) 974 } 975 976 func testAccAWSLambdaConfigPython27Runtime(rName, rSt string) string { 977 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 978 resource "aws_lambda_function" "lambda_function_test" { 979 filename = "test-fixtures/lambdatest.zip" 980 function_name = "%s" 981 role = "${aws_iam_role.iam_for_lambda.arn}" 982 handler = "exports.example" 983 runtime = "python2.7" 984 } 985 `, rName) 986 } 987 988 func testAccAWSLambdaConfigJava8Runtime(rName, rSt string) string { 989 return fmt.Sprintf(baseAccAWSLambdaConfig(rSt)+` 990 resource "aws_lambda_function" "lambda_function_test" { 991 filename = "test-fixtures/lambdatest.zip" 992 function_name = "%s" 993 role = "${aws_iam_role.iam_for_lambda.arn}" 994 handler = "exports.example" 995 runtime = "java8" 996 } 997 `, rName) 998 } 999 1000 const testAccAWSLambdaFunctionConfig_local_tpl = ` 1001 resource "aws_iam_role" "iam_for_lambda" { 1002 name = "iam_for_lambda" 1003 assume_role_policy = <<EOF 1004 { 1005 "Version": "2012-10-17", 1006 "Statement": [ 1007 { 1008 "Action": "sts:AssumeRole", 1009 "Principal": { 1010 "Service": "lambda.amazonaws.com" 1011 }, 1012 "Effect": "Allow", 1013 "Sid": "" 1014 } 1015 ] 1016 } 1017 EOF 1018 } 1019 resource "aws_lambda_function" "lambda_function_local" { 1020 filename = "%s" 1021 source_code_hash = "${base64sha256(file("%s"))}" 1022 function_name = "tf_acc_lambda_name_local" 1023 role = "${aws_iam_role.iam_for_lambda.arn}" 1024 handler = "exports.example" 1025 runtime = "nodejs4.3" 1026 } 1027 ` 1028 1029 func genAWSLambdaFunctionConfig_local(filePath string) string { 1030 return fmt.Sprintf(testAccAWSLambdaFunctionConfig_local_tpl, 1031 filePath, filePath) 1032 } 1033 1034 func genAWSLambdaFunctionConfig_local_name_only(filePath, rName string) string { 1035 return testAccAWSLambdaFunctionConfig_local_name_only_tpl(filePath, rName) 1036 } 1037 1038 func testAccAWSLambdaFunctionConfig_local_name_only_tpl(filePath, rName string) string { 1039 return fmt.Sprintf(` 1040 resource "aws_iam_role" "iam_for_lambda" { 1041 name = "%s" 1042 assume_role_policy = <<EOF 1043 { 1044 "Version": "2012-10-17", 1045 "Statement": [ 1046 { 1047 "Action": "sts:AssumeRole", 1048 "Principal": { 1049 "Service": "lambda.amazonaws.com" 1050 }, 1051 "Effect": "Allow", 1052 "Sid": "" 1053 } 1054 ] 1055 } 1056 EOF 1057 } 1058 resource "aws_lambda_function" "lambda_function_local" { 1059 filename = "%s" 1060 function_name = "%s" 1061 role = "${aws_iam_role.iam_for_lambda.arn}" 1062 handler = "exports.example" 1063 runtime = "nodejs4.3" 1064 }`, rName, filePath, rName) 1065 } 1066 1067 const testAccAWSLambdaFunctionConfig_s3_tpl = ` 1068 resource "aws_s3_bucket" "artifacts" { 1069 bucket = "%s" 1070 acl = "private" 1071 force_destroy = true 1072 versioning { 1073 enabled = true 1074 } 1075 } 1076 resource "aws_s3_bucket_object" "o" { 1077 bucket = "${aws_s3_bucket.artifacts.bucket}" 1078 key = "%s" 1079 source = "%s" 1080 etag = "${md5(file("%s"))}" 1081 } 1082 resource "aws_iam_role" "iam_for_lambda" { 1083 name = "iam_for_lambda" 1084 assume_role_policy = <<EOF 1085 { 1086 "Version": "2012-10-17", 1087 "Statement": [ 1088 { 1089 "Action": "sts:AssumeRole", 1090 "Principal": { 1091 "Service": "lambda.amazonaws.com" 1092 }, 1093 "Effect": "Allow", 1094 "Sid": "" 1095 } 1096 ] 1097 } 1098 EOF 1099 } 1100 resource "aws_lambda_function" "lambda_function_s3" { 1101 s3_bucket = "${aws_s3_bucket_object.o.bucket}" 1102 s3_key = "${aws_s3_bucket_object.o.key}" 1103 s3_object_version = "${aws_s3_bucket_object.o.version_id}" 1104 function_name = "tf_acc_lambda_name_s3" 1105 role = "${aws_iam_role.iam_for_lambda.arn}" 1106 handler = "exports.example" 1107 runtime = "nodejs4.3" 1108 } 1109 ` 1110 1111 func genAWSLambdaFunctionConfig_s3(bucket, key, path string) string { 1112 return fmt.Sprintf(testAccAWSLambdaFunctionConfig_s3_tpl, 1113 bucket, key, path, path) 1114 } 1115 1116 func testAccAWSLambdaFunctionConfig_s3_unversioned_tpl(rName, bucketName, key, path string) string { 1117 return fmt.Sprintf(` 1118 resource "aws_s3_bucket" "artifacts" { 1119 bucket = "%s" 1120 acl = "private" 1121 force_destroy = true 1122 } 1123 resource "aws_s3_bucket_object" "o" { 1124 bucket = "${aws_s3_bucket.artifacts.bucket}" 1125 key = "%s" 1126 source = "%s" 1127 etag = "${md5(file("%s"))}" 1128 } 1129 resource "aws_iam_role" "iam_for_lambda" { 1130 name = "%s" 1131 assume_role_policy = <<EOF 1132 { 1133 "Version": "2012-10-17", 1134 "Statement": [ 1135 { 1136 "Action": "sts:AssumeRole", 1137 "Principal": { 1138 "Service": "lambda.amazonaws.com" 1139 }, 1140 "Effect": "Allow", 1141 "Sid": "" 1142 } 1143 ] 1144 } 1145 EOF 1146 } 1147 resource "aws_lambda_function" "lambda_function_s3" { 1148 s3_bucket = "${aws_s3_bucket_object.o.bucket}" 1149 s3_key = "${aws_s3_bucket_object.o.key}" 1150 function_name = "tf_acc_lambda_name_s3_unversioned" 1151 role = "${aws_iam_role.iam_for_lambda.arn}" 1152 handler = "exports.example" 1153 runtime = "nodejs4.3" 1154 }`, bucketName, key, path, path, rName) 1155 }