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