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