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