github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_lambda_permission_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/aws/aws-sdk-go/aws"
    12  	"github.com/aws/aws-sdk-go/aws/awserr"
    13  	"github.com/aws/aws-sdk-go/service/lambda"
    14  	"github.com/hashicorp/terraform/helper/acctest"
    15  	"github.com/hashicorp/terraform/helper/resource"
    16  	"github.com/hashicorp/terraform/terraform"
    17  )
    18  
    19  func TestLambdaPermissionUnmarshalling(t *testing.T) {
    20  	v := LambdaPolicy{}
    21  	err := json.Unmarshal(testLambdaPolicy, &v)
    22  	if err != nil {
    23  		t.Fatalf("Expected no error when unmarshalling: %s", err)
    24  	}
    25  
    26  	expectedSid := "36fe77d9-a4ae-13fb-8beb-5dc6821d5291"
    27  	if v.Statement[0].Sid != expectedSid {
    28  		t.Fatalf("Expected Sid to match (%q != %q)", v.Statement[0].Sid, expectedSid)
    29  	}
    30  
    31  	expectedFunctionName := "arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction"
    32  	if v.Statement[0].Resource != expectedFunctionName {
    33  		t.Fatalf("Expected function name to match (%q != %q)", v.Statement[0].Resource, expectedFunctionName)
    34  	}
    35  
    36  	expectedAction := "lambda:InvokeFunction"
    37  	if v.Statement[0].Action != expectedAction {
    38  		t.Fatalf("Expected Action to match (%q != %q)", v.Statement[0].Action, expectedAction)
    39  	}
    40  
    41  	expectedPrincipal := "events.amazonaws.com"
    42  	if v.Statement[0].Principal["Service"] != expectedPrincipal {
    43  		t.Fatalf("Expected Principal to match (%q != %q)", v.Statement[0].Principal["Service"], expectedPrincipal)
    44  	}
    45  
    46  	expectedSourceAccount := "319201112229"
    47  	if v.Statement[0].Condition["StringEquals"]["AWS:SourceAccount"] != expectedSourceAccount {
    48  		t.Fatalf("Expected Source Account to match (%q != %q)",
    49  			v.Statement[0].Condition["StringEquals"]["AWS:SourceAccount"],
    50  			expectedSourceAccount)
    51  	}
    52  }
    53  
    54  func TestLambdaPermissionGetQualifierFromLambdaAliasOrVersionArn_alias(t *testing.T) {
    55  	arnWithAlias := "arn:aws:lambda:us-west-2:187636751137:function:lambda_function_name:testalias"
    56  	expectedQualifier := "testalias"
    57  	qualifier, err := getQualifierFromLambdaAliasOrVersionArn(arnWithAlias)
    58  	if err != nil {
    59  		t.Fatalf("Expected no error when getting qualifier: %s", err)
    60  	}
    61  	if qualifier != expectedQualifier {
    62  		t.Fatalf("Expected qualifier to match (%q != %q)", qualifier, expectedQualifier)
    63  	}
    64  }
    65  
    66  func TestLambdaPermissionGetQualifierFromLambdaAliasOrVersionArn_govcloud(t *testing.T) {
    67  	arnWithAlias := "arn:aws-us-gov:lambda:us-west-2:187636751137:function:lambda_function_name:testalias"
    68  	expectedQualifier := "testalias"
    69  	qualifier, err := getQualifierFromLambdaAliasOrVersionArn(arnWithAlias)
    70  	if err != nil {
    71  		t.Fatalf("Expected no error when getting qualifier: %s", err)
    72  	}
    73  	if qualifier != expectedQualifier {
    74  		t.Fatalf("Expected qualifier to match (%q != %q)", qualifier, expectedQualifier)
    75  	}
    76  }
    77  
    78  func TestLambdaPermissionGetQualifierFromLambdaAliasOrVersionArn_version(t *testing.T) {
    79  	arnWithVersion := "arn:aws:lambda:us-west-2:187636751137:function:lambda_function_name:223"
    80  	expectedQualifier := "223"
    81  	qualifier, err := getQualifierFromLambdaAliasOrVersionArn(arnWithVersion)
    82  	if err != nil {
    83  		t.Fatalf("Expected no error when getting qualifier: %s", err)
    84  	}
    85  	if qualifier != expectedQualifier {
    86  		t.Fatalf("Expected qualifier to match (%q != %q)", qualifier, expectedQualifier)
    87  	}
    88  }
    89  
    90  func TestLambdaPermissionGetQualifierFromLambdaAliasOrVersionArn_invalid(t *testing.T) {
    91  	invalidArn := "arn:aws:lambda:us-west-2:187636751137:function:lambda_function_name"
    92  	qualifier, err := getQualifierFromLambdaAliasOrVersionArn(invalidArn)
    93  	if err == nil {
    94  		t.Fatalf("Expected error when getting qualifier")
    95  	}
    96  	if qualifier != "" {
    97  		t.Fatalf("Expected qualifier to be empty (%q)", qualifier)
    98  	}
    99  
   100  	// with trailing colon
   101  	invalidArn = "arn:aws:lambda:us-west-2:187636751137:function:lambda_function_name:"
   102  	qualifier, err = getQualifierFromLambdaAliasOrVersionArn(invalidArn)
   103  	if err == nil {
   104  		t.Fatalf("Expected error when getting qualifier")
   105  	}
   106  	if qualifier != "" {
   107  		t.Fatalf("Expected qualifier to be empty (%q)", qualifier)
   108  	}
   109  }
   110  
   111  func TestLambdaPermissionGetFunctionNameFromLambdaArn_invalid(t *testing.T) {
   112  	invalidArn := "arn:aws:lambda:us-west-2:187636751137:function:"
   113  	fn, err := getFunctionNameFromLambdaArn(invalidArn)
   114  	if err == nil {
   115  		t.Fatalf("Expected error when parsing invalid ARN (%q)", invalidArn)
   116  	}
   117  	if fn != "" {
   118  		t.Fatalf("Expected empty string when parsing invalid ARN (%q)", invalidArn)
   119  	}
   120  }
   121  
   122  func TestLambdaPermissionGetFunctionNameFromLambdaArn_valid(t *testing.T) {
   123  	validArn := "arn:aws:lambda:us-west-2:187636751137:function:lambda_function_name"
   124  	fn, err := getFunctionNameFromLambdaArn(validArn)
   125  	if err != nil {
   126  		t.Fatalf("Expected no error (%q): %q", validArn, err)
   127  	}
   128  	expectedFunctionname := "lambda_function_name"
   129  	if fn != expectedFunctionname {
   130  		t.Fatalf("Expected Lambda function name to match (%q != %q)",
   131  			validArn, expectedFunctionname)
   132  	}
   133  
   134  	// With qualifier
   135  	validArn = "arn:aws:lambda:us-west-2:187636751137:function:lambda_function_name:12"
   136  	fn, err = getFunctionNameFromLambdaArn(validArn)
   137  	if err != nil {
   138  		t.Fatalf("Expected no error (%q): %q", validArn, err)
   139  	}
   140  	expectedFunctionname = "lambda_function_name"
   141  	if fn != expectedFunctionname {
   142  		t.Fatalf("Expected Lambda function name to match (%q != %q)",
   143  			validArn, expectedFunctionname)
   144  	}
   145  }
   146  
   147  func TestAccAWSLambdaPermission_basic(t *testing.T) {
   148  	var statement LambdaPolicyStatement
   149  	endsWithFuncName := regexp.MustCompile(":function:lambda_function_name_perm$")
   150  
   151  	rName := fmt.Sprintf("tf_iam_%d", acctest.RandInt())
   152  
   153  	resource.Test(t, resource.TestCase{
   154  		PreCheck:     func() { testAccPreCheck(t) },
   155  		Providers:    testAccProviders,
   156  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   157  		Steps: []resource.TestStep{
   158  			{
   159  				Config: testAccAWSLambdaPermissionConfig(rName),
   160  				Check: resource.ComposeTestCheckFunc(
   161  					testAccCheckLambdaPermissionExists("aws_lambda_permission.allow_cloudwatch", &statement),
   162  					resource.TestCheckResourceAttr("aws_lambda_permission.allow_cloudwatch", "action", "lambda:InvokeFunction"),
   163  					resource.TestCheckResourceAttr("aws_lambda_permission.allow_cloudwatch", "principal", "events.amazonaws.com"),
   164  					resource.TestCheckResourceAttr("aws_lambda_permission.allow_cloudwatch", "statement_id", "AllowExecutionFromCloudWatch"),
   165  					resource.TestCheckResourceAttr("aws_lambda_permission.allow_cloudwatch", "qualifier", ""),
   166  					resource.TestMatchResourceAttr("aws_lambda_permission.allow_cloudwatch", "function_name", endsWithFuncName),
   167  				),
   168  			},
   169  		},
   170  	})
   171  }
   172  
   173  func TestAccAWSLambdaPermission_withRawFunctionName(t *testing.T) {
   174  	var statement LambdaPolicyStatement
   175  	endsWithFuncName := regexp.MustCompile(":function:lambda_function_name_perm_raw_func_name$")
   176  
   177  	resource.Test(t, resource.TestCase{
   178  		PreCheck:     func() { testAccPreCheck(t) },
   179  		Providers:    testAccProviders,
   180  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   181  		Steps: []resource.TestStep{
   182  			{
   183  				Config: testAccAWSLambdaPermissionConfig_withRawFunctionName,
   184  				Check: resource.ComposeTestCheckFunc(
   185  					testAccCheckLambdaPermissionExists("aws_lambda_permission.with_raw_func_name", &statement),
   186  					resource.TestCheckResourceAttr("aws_lambda_permission.with_raw_func_name", "action", "lambda:InvokeFunction"),
   187  					resource.TestCheckResourceAttr("aws_lambda_permission.with_raw_func_name", "principal", "events.amazonaws.com"),
   188  					resource.TestCheckResourceAttr("aws_lambda_permission.with_raw_func_name", "statement_id", "AllowExecutionWithRawFuncName"),
   189  					resource.TestMatchResourceAttr("aws_lambda_permission.with_raw_func_name", "function_name", endsWithFuncName),
   190  				),
   191  			},
   192  		},
   193  	})
   194  }
   195  
   196  func TestAccAWSLambdaPermission_withQualifier(t *testing.T) {
   197  	var statement LambdaPolicyStatement
   198  	endsWithFuncName := regexp.MustCompile(":function:lambda_function_name_perm_qualifier$")
   199  
   200  	resource.Test(t, resource.TestCase{
   201  		PreCheck:     func() { testAccPreCheck(t) },
   202  		Providers:    testAccProviders,
   203  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   204  		Steps: []resource.TestStep{
   205  			{
   206  				Config: testAccAWSLambdaPermissionConfig_withQualifier,
   207  				Check: resource.ComposeTestCheckFunc(
   208  					testAccCheckLambdaPermissionExists("aws_lambda_permission.with_qualifier", &statement),
   209  					resource.TestCheckResourceAttr("aws_lambda_permission.with_qualifier", "action", "lambda:InvokeFunction"),
   210  					resource.TestCheckResourceAttr("aws_lambda_permission.with_qualifier", "principal", "events.amazonaws.com"),
   211  					resource.TestCheckResourceAttr("aws_lambda_permission.with_qualifier", "statement_id", "AllowExecutionWithQualifier"),
   212  					resource.TestMatchResourceAttr("aws_lambda_permission.with_qualifier", "function_name", endsWithFuncName),
   213  					resource.TestCheckResourceAttr("aws_lambda_permission.with_qualifier", "qualifier", "testalias_perm_qualifier"),
   214  				),
   215  			},
   216  		},
   217  	})
   218  }
   219  
   220  func TestAccAWSLambdaPermission_multiplePerms(t *testing.T) {
   221  	var firstStatement LambdaPolicyStatement
   222  	var firstStatementModified LambdaPolicyStatement
   223  
   224  	var secondStatement LambdaPolicyStatement
   225  	var secondStatementModified LambdaPolicyStatement
   226  
   227  	var thirdStatement LambdaPolicyStatement
   228  
   229  	resource.Test(t, resource.TestCase{
   230  		PreCheck:     func() { testAccPreCheck(t) },
   231  		Providers:    testAccProviders,
   232  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   233  		Steps: []resource.TestStep{
   234  			{
   235  				Config: testAccAWSLambdaPermissionConfig_multiplePerms,
   236  				Check: resource.ComposeTestCheckFunc(
   237  					// 1st
   238  					testAccCheckLambdaPermissionExists("aws_lambda_permission.first", &firstStatement),
   239  					resource.TestCheckResourceAttr("aws_lambda_permission.first", "action", "lambda:InvokeFunction"),
   240  					resource.TestCheckResourceAttr("aws_lambda_permission.first", "principal", "events.amazonaws.com"),
   241  					resource.TestCheckResourceAttr("aws_lambda_permission.first", "statement_id", "AllowExecutionFirst"),
   242  					resource.TestMatchResourceAttr("aws_lambda_permission.first", "function_name",
   243  						regexp.MustCompile(":function:lambda_function_name_perm_multiperms$")),
   244  					// 2nd
   245  					testAccCheckLambdaPermissionExists("aws_lambda_permission.second", &firstStatementModified),
   246  					resource.TestCheckResourceAttr("aws_lambda_permission.second", "action", "lambda:*"),
   247  					resource.TestCheckResourceAttr("aws_lambda_permission.second", "principal", "events.amazonaws.com"),
   248  					resource.TestCheckResourceAttr("aws_lambda_permission.second", "statement_id", "AllowExecutionSecond"),
   249  					resource.TestMatchResourceAttr("aws_lambda_permission.second", "function_name",
   250  						regexp.MustCompile(":function:lambda_function_name_perm_multiperms$")),
   251  				),
   252  			},
   253  			{
   254  				Config: testAccAWSLambdaPermissionConfig_multiplePermsModified,
   255  				Check: resource.ComposeTestCheckFunc(
   256  					// 1st
   257  					testAccCheckLambdaPermissionExists("aws_lambda_permission.first", &secondStatement),
   258  					resource.TestCheckResourceAttr("aws_lambda_permission.first", "action", "lambda:InvokeFunction"),
   259  					resource.TestCheckResourceAttr("aws_lambda_permission.first", "principal", "events.amazonaws.com"),
   260  					resource.TestCheckResourceAttr("aws_lambda_permission.first", "statement_id", "AllowExecutionFirst"),
   261  					resource.TestMatchResourceAttr("aws_lambda_permission.first", "function_name",
   262  						regexp.MustCompile(":function:lambda_function_name_perm_multiperms$")),
   263  					// 2nd
   264  					testAccCheckLambdaPermissionExists("aws_lambda_permission.sec0nd", &secondStatementModified),
   265  					resource.TestCheckResourceAttr("aws_lambda_permission.sec0nd", "action", "lambda:*"),
   266  					resource.TestCheckResourceAttr("aws_lambda_permission.sec0nd", "principal", "events.amazonaws.com"),
   267  					resource.TestCheckResourceAttr("aws_lambda_permission.sec0nd", "statement_id", "AllowExecutionSec0nd"),
   268  					resource.TestMatchResourceAttr("aws_lambda_permission.sec0nd", "function_name",
   269  						regexp.MustCompile(":function:lambda_function_name_perm_multiperms$")),
   270  					// 3rd
   271  					testAccCheckLambdaPermissionExists("aws_lambda_permission.third", &thirdStatement),
   272  					resource.TestCheckResourceAttr("aws_lambda_permission.third", "action", "lambda:*"),
   273  					resource.TestCheckResourceAttr("aws_lambda_permission.third", "principal", "events.amazonaws.com"),
   274  					resource.TestCheckResourceAttr("aws_lambda_permission.third", "statement_id", "AllowExecutionThird"),
   275  					resource.TestMatchResourceAttr("aws_lambda_permission.third", "function_name",
   276  						regexp.MustCompile(":function:lambda_function_name_perm_multiperms$")),
   277  				),
   278  			},
   279  		},
   280  	})
   281  }
   282  
   283  func TestAccAWSLambdaPermission_withS3(t *testing.T) {
   284  	rInt := acctest.RandInt()
   285  
   286  	var statement LambdaPolicyStatement
   287  	endsWithFuncName := regexp.MustCompile(":function:lambda_function_name_perm_s3$")
   288  
   289  	resource.Test(t, resource.TestCase{
   290  		PreCheck:     func() { testAccPreCheck(t) },
   291  		Providers:    testAccProviders,
   292  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   293  		Steps: []resource.TestStep{
   294  			{
   295  				Config: fmt.Sprintf(testAccAWSLambdaPermissionConfig_withS3_tpl, rInt),
   296  				Check: resource.ComposeTestCheckFunc(
   297  					testAccCheckLambdaPermissionExists("aws_lambda_permission.with_s3", &statement),
   298  					resource.TestCheckResourceAttr("aws_lambda_permission.with_s3", "action", "lambda:InvokeFunction"),
   299  					resource.TestCheckResourceAttr("aws_lambda_permission.with_s3", "principal", "s3.amazonaws.com"),
   300  					resource.TestCheckResourceAttr("aws_lambda_permission.with_s3", "statement_id", "AllowExecutionFromS3"),
   301  					resource.TestMatchResourceAttr("aws_lambda_permission.with_s3", "function_name", endsWithFuncName),
   302  					resource.TestCheckResourceAttr("aws_lambda_permission.with_s3", "source_arn",
   303  						fmt.Sprintf("arn:aws:s3:::tf-acc-towards-lambda-%d", rInt)),
   304  				),
   305  			},
   306  		},
   307  	})
   308  }
   309  
   310  func TestAccAWSLambdaPermission_withSNS(t *testing.T) {
   311  	var statement LambdaPolicyStatement
   312  	endsWithFuncName := regexp.MustCompile(":function:lambda_function_name_perm_sns$")
   313  	endsWithTopicName := regexp.MustCompile(":tf-acc-user-updates-topic$")
   314  
   315  	resource.Test(t, resource.TestCase{
   316  		PreCheck:     func() { testAccPreCheck(t) },
   317  		Providers:    testAccProviders,
   318  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   319  		Steps: []resource.TestStep{
   320  			{
   321  				Config: testAccAWSLambdaPermissionConfig_withSNS,
   322  				Check: resource.ComposeTestCheckFunc(
   323  					testAccCheckLambdaPermissionExists("aws_lambda_permission.with_sns", &statement),
   324  					resource.TestCheckResourceAttr("aws_lambda_permission.with_sns", "action", "lambda:InvokeFunction"),
   325  					resource.TestCheckResourceAttr("aws_lambda_permission.with_sns", "principal", "sns.amazonaws.com"),
   326  					resource.TestCheckResourceAttr("aws_lambda_permission.with_sns", "statement_id", "AllowExecutionFromSNS"),
   327  					resource.TestMatchResourceAttr("aws_lambda_permission.with_sns", "function_name", endsWithFuncName),
   328  					resource.TestMatchResourceAttr("aws_lambda_permission.with_sns", "source_arn", endsWithTopicName),
   329  				),
   330  			},
   331  		},
   332  	})
   333  }
   334  
   335  func TestAccAWSLambdaPermission_withIAMRole(t *testing.T) {
   336  	var statement LambdaPolicyStatement
   337  	endsWithFuncName := regexp.MustCompile(":function:lambda_function_name_perm_iamrole$")
   338  	endsWithRoleName := regexp.MustCompile("/iam_for_lambda_perm_iamrole$")
   339  
   340  	resource.Test(t, resource.TestCase{
   341  		PreCheck:     func() { testAccPreCheck(t) },
   342  		Providers:    testAccProviders,
   343  		CheckDestroy: testAccCheckAWSLambdaPermissionDestroy,
   344  		Steps: []resource.TestStep{
   345  			{
   346  				Config: testAccAWSLambdaPermissionConfig_withIAMRole,
   347  				Check: resource.ComposeTestCheckFunc(
   348  					testAccCheckLambdaPermissionExists("aws_lambda_permission.iam_role", &statement),
   349  					resource.TestCheckResourceAttr("aws_lambda_permission.iam_role", "action", "lambda:InvokeFunction"),
   350  					resource.TestMatchResourceAttr("aws_lambda_permission.iam_role", "principal", endsWithRoleName),
   351  					resource.TestCheckResourceAttr("aws_lambda_permission.iam_role", "statement_id", "AllowExecutionFromIAMRole"),
   352  					resource.TestMatchResourceAttr("aws_lambda_permission.iam_role", "function_name", endsWithFuncName),
   353  				),
   354  			},
   355  		},
   356  	})
   357  }
   358  
   359  func testAccCheckLambdaPermissionExists(n string, statement *LambdaPolicyStatement) resource.TestCheckFunc {
   360  	return func(s *terraform.State) error {
   361  		rs, ok := s.RootModule().Resources[n]
   362  		if !ok {
   363  			return fmt.Errorf("Not found: %s", n)
   364  		}
   365  
   366  		conn := testAccProvider.Meta().(*AWSClient).lambdaconn
   367  
   368  		// IAM is eventually consistent
   369  		var foundStatement *LambdaPolicyStatement
   370  		err := resource.Retry(5*time.Minute, func() *resource.RetryError {
   371  			var err error
   372  			foundStatement, err = lambdaPermissionExists(rs, conn)
   373  			if err != nil {
   374  				if strings.HasPrefix(err.Error(), "ResourceNotFoundException") {
   375  					return resource.RetryableError(err)
   376  				}
   377  				if strings.HasPrefix(err.Error(), "Lambda policy not found") {
   378  					return resource.RetryableError(err)
   379  				}
   380  				if strings.HasPrefix(err.Error(), "Failed to find statement") {
   381  					return resource.RetryableError(err)
   382  				}
   383  				return resource.NonRetryableError(err)
   384  			}
   385  			return nil
   386  		})
   387  		if err != nil {
   388  			return err
   389  		}
   390  
   391  		*statement = *foundStatement
   392  
   393  		return nil
   394  	}
   395  }
   396  
   397  func testAccCheckAWSLambdaPermissionDestroy(s *terraform.State) error {
   398  	conn := testAccProvider.Meta().(*AWSClient).lambdaconn
   399  
   400  	for _, rs := range s.RootModule().Resources {
   401  		if rs.Type != "aws_lambda_permission" {
   402  			continue
   403  		}
   404  
   405  		// IAM is eventually consistent
   406  		err := resource.Retry(5*time.Minute, func() *resource.RetryError {
   407  			err := isLambdaPermissionGone(rs, conn)
   408  			if err != nil {
   409  				if !strings.HasPrefix(err.Error(), "Error unmarshalling Lambda policy") {
   410  					return resource.RetryableError(err)
   411  				}
   412  				return resource.NonRetryableError(err)
   413  			}
   414  			return nil
   415  		})
   416  		if err != nil {
   417  			return err
   418  		}
   419  	}
   420  
   421  	return nil
   422  }
   423  
   424  func isLambdaPermissionGone(rs *terraform.ResourceState, conn *lambda.Lambda) error {
   425  	params := &lambda.GetPolicyInput{
   426  		FunctionName: aws.String(rs.Primary.Attributes["function_name"]),
   427  	}
   428  	if v, ok := rs.Primary.Attributes["qualifier"]; ok && v != "" {
   429  		params.Qualifier = aws.String(v)
   430  	}
   431  
   432  	resp, err := conn.GetPolicy(params)
   433  	if awsErr, ok := err.(awserr.Error); ok {
   434  		if awsErr.Code() == "ResourceNotFoundException" {
   435  			// no policy found => all statements deleted
   436  			return nil
   437  		}
   438  	}
   439  	if err != nil {
   440  		return fmt.Errorf("Unexpected error when checking existence of Lambda permission: %s\n%s",
   441  			rs.Primary.ID, err)
   442  	}
   443  
   444  	policyInBytes := []byte(*resp.Policy)
   445  	policy := LambdaPolicy{}
   446  	err = json.Unmarshal(policyInBytes, &policy)
   447  	if err != nil {
   448  		return fmt.Errorf("Error unmarshalling Lambda policy (%s): %s", *resp.Policy, err)
   449  	}
   450  
   451  	state, err := findLambdaPolicyStatementById(&policy, rs.Primary.ID)
   452  	if err != nil {
   453  		// statement not found => deleted
   454  		return nil
   455  	}
   456  
   457  	return fmt.Errorf("Policy statement expected to be gone (%s):\n%s",
   458  		rs.Primary.ID, *state)
   459  }
   460  
   461  func lambdaPermissionExists(rs *terraform.ResourceState, conn *lambda.Lambda) (*LambdaPolicyStatement, error) {
   462  	params := &lambda.GetPolicyInput{
   463  		FunctionName: aws.String(rs.Primary.Attributes["function_name"]),
   464  	}
   465  	if v, ok := rs.Primary.Attributes["qualifier"]; ok && v != "" {
   466  		params.Qualifier = aws.String(v)
   467  	}
   468  
   469  	resp, err := conn.GetPolicy(params)
   470  	if err != nil {
   471  		return nil, fmt.Errorf("Lambda policy not found: %q", err)
   472  	}
   473  
   474  	if resp.Policy == nil {
   475  		return nil, fmt.Errorf("Received Lambda policy is empty")
   476  	}
   477  
   478  	policyInBytes := []byte(*resp.Policy)
   479  	policy := LambdaPolicy{}
   480  	err = json.Unmarshal(policyInBytes, &policy)
   481  	if err != nil {
   482  		return nil, fmt.Errorf("Error unmarshalling Lambda policy: %s", err)
   483  	}
   484  
   485  	return findLambdaPolicyStatementById(&policy, rs.Primary.ID)
   486  }
   487  
   488  func testAccAWSLambdaPermissionConfig(rName string) string {
   489  	return fmt.Sprintf(`
   490  resource "aws_lambda_permission" "allow_cloudwatch" {
   491      statement_id = "AllowExecutionFromCloudWatch"
   492      action = "lambda:InvokeFunction"
   493      function_name = "${aws_lambda_function.test_lambda.arn}"
   494      principal = "events.amazonaws.com"
   495  }
   496  
   497  resource "aws_lambda_function" "test_lambda" {
   498      filename = "test-fixtures/lambdatest.zip"
   499      function_name = "lambda_function_name_perm"
   500      role = "${aws_iam_role.iam_for_lambda.arn}"
   501      handler = "exports.handler"
   502      runtime = "nodejs4.3"
   503  }
   504  
   505  resource "aws_iam_role" "iam_for_lambda" {
   506      name = "%s"
   507      assume_role_policy = <<EOF
   508  {
   509    "Version": "2012-10-17",
   510    "Statement": [
   511      {
   512        "Action": "sts:AssumeRole",
   513        "Principal": {
   514          "Service": "lambda.amazonaws.com"
   515        },
   516        "Effect": "Allow",
   517        "Sid": ""
   518      }
   519    ]
   520  }
   521  EOF
   522  }`, rName)
   523  }
   524  
   525  var testAccAWSLambdaPermissionConfig_withRawFunctionName = `
   526  resource "aws_lambda_permission" "with_raw_func_name" {
   527      statement_id = "AllowExecutionWithRawFuncName"
   528      action = "lambda:InvokeFunction"
   529      function_name = "${aws_lambda_function.test_lambda.arn}"
   530      principal = "events.amazonaws.com"
   531  }
   532  
   533  resource "aws_lambda_function" "test_lambda" {
   534      filename = "test-fixtures/lambdatest.zip"
   535      function_name = "lambda_function_name_perm_raw_func_name"
   536      role = "${aws_iam_role.iam_for_lambda.arn}"
   537      handler = "exports.handler"
   538      runtime = "nodejs4.3"
   539  }
   540  
   541  resource "aws_iam_role" "iam_for_lambda" {
   542      name = "iam_for_lambda_perm_raw_func_name"
   543      assume_role_policy = <<EOF
   544  {
   545    "Version": "2012-10-17",
   546    "Statement": [
   547      {
   548        "Action": "sts:AssumeRole",
   549        "Principal": {
   550          "Service": "lambda.amazonaws.com"
   551        },
   552        "Effect": "Allow",
   553        "Sid": ""
   554      }
   555    ]
   556  }
   557  EOF
   558  }
   559  `
   560  
   561  var testAccAWSLambdaPermissionConfig_withQualifier = `
   562  resource "aws_lambda_permission" "with_qualifier" {
   563      statement_id = "AllowExecutionWithQualifier"
   564      action = "lambda:InvokeFunction"
   565      function_name = "${aws_lambda_function.test_lambda.arn}"
   566      principal = "events.amazonaws.com"
   567      source_account = "111122223333"
   568      source_arn = "arn:aws:events:eu-west-1:111122223333:rule/RunDaily"
   569      qualifier = "${aws_lambda_alias.test_alias.name}"
   570  }
   571  
   572  resource "aws_lambda_alias" "test_alias" {
   573      name = "testalias_perm_qualifier"
   574      description = "a sample description"
   575      function_name = "${aws_lambda_function.test_lambda.arn}"
   576      function_version = "$LATEST"
   577  }
   578  
   579  resource "aws_lambda_function" "test_lambda" {
   580      filename = "test-fixtures/lambdatest.zip"
   581      function_name = "lambda_function_name_perm_qualifier"
   582      role = "${aws_iam_role.iam_for_lambda.arn}"
   583      handler = "exports.handler"
   584      runtime = "nodejs4.3"
   585  }
   586  
   587  resource "aws_iam_role" "iam_for_lambda" {
   588      name = "iam_for_lambda_perm_qualifier"
   589      assume_role_policy = <<EOF
   590  {
   591    "Version": "2012-10-17",
   592    "Statement": [
   593      {
   594        "Action": "sts:AssumeRole",
   595        "Principal": {
   596          "Service": "lambda.amazonaws.com"
   597        },
   598        "Effect": "Allow",
   599        "Sid": ""
   600      }
   601    ]
   602  }
   603  EOF
   604  }
   605  `
   606  
   607  var testAccAWSLambdaPermissionConfig_multiplePerms_tpl = `
   608  resource "aws_lambda_permission" "first" {
   609      statement_id = "AllowExecutionFirst"
   610      action = "lambda:InvokeFunction"
   611      function_name = "${aws_lambda_function.test_lambda.arn}"
   612      principal = "events.amazonaws.com"
   613  }
   614  
   615  resource "aws_lambda_permission" "%s" {
   616      statement_id = "%s"
   617      action = "lambda:*"
   618      function_name = "${aws_lambda_function.test_lambda.arn}"
   619      principal = "events.amazonaws.com"
   620  }
   621  %s
   622  
   623  resource "aws_lambda_function" "test_lambda" {
   624      filename = "test-fixtures/lambdatest.zip"
   625      function_name = "lambda_function_name_perm_multiperms"
   626      role = "${aws_iam_role.iam_for_lambda.arn}"
   627      handler = "exports.handler"
   628      runtime = "nodejs4.3"
   629  }
   630  
   631  resource "aws_iam_role" "iam_for_lambda" {
   632      name = "iam_for_lambda_perm_multi_perms"
   633      assume_role_policy = <<EOF
   634  {
   635    "Version": "2012-10-17",
   636    "Statement": [
   637      {
   638        "Action": "sts:AssumeRole",
   639        "Principal": {
   640          "Service": "lambda.amazonaws.com"
   641        },
   642        "Effect": "Allow",
   643        "Sid": ""
   644      }
   645    ]
   646  }
   647  EOF
   648  }
   649  `
   650  
   651  var testAccAWSLambdaPermissionConfig_multiplePerms = fmt.Sprintf(
   652  	testAccAWSLambdaPermissionConfig_multiplePerms_tpl, "second", "AllowExecutionSecond", "")
   653  var testAccAWSLambdaPermissionConfig_multiplePermsModified = fmt.Sprintf(
   654  	testAccAWSLambdaPermissionConfig_multiplePerms_tpl, "sec0nd", "AllowExecutionSec0nd", `
   655  resource "aws_lambda_permission" "third" {
   656      statement_id = "AllowExecutionThird"
   657      action = "lambda:*"
   658      function_name = "${aws_lambda_function.test_lambda.arn}"
   659      principal = "events.amazonaws.com"
   660  }`)
   661  
   662  var testAccAWSLambdaPermissionConfig_withS3_tpl = `
   663  resource "aws_lambda_permission" "with_s3" {
   664      statement_id = "AllowExecutionFromS3"
   665      action = "lambda:InvokeFunction"
   666      function_name = "${aws_lambda_function.my-func.arn}"
   667      principal = "s3.amazonaws.com"
   668      source_arn = "${aws_s3_bucket.default.arn}"
   669  }
   670  
   671  resource "aws_s3_bucket" "default" {
   672  	bucket = "tf-acc-towards-lambda-%d"
   673      acl = "private"
   674  }
   675  
   676  resource "aws_lambda_function" "my-func" {
   677      filename = "test-fixtures/lambdatest.zip"
   678      function_name = "lambda_function_name_perm_s3"
   679      role = "${aws_iam_role.police.arn}"
   680      handler = "exports.handler"
   681      runtime = "nodejs4.3"
   682  }
   683  
   684  resource "aws_iam_role" "police" {
   685      name = "iam_for_lambda_perm_with_s3"
   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  
   704  var testAccAWSLambdaPermissionConfig_withSNS = `
   705  resource "aws_lambda_permission" "with_sns" {
   706      statement_id = "AllowExecutionFromSNS"
   707      action = "lambda:InvokeFunction"
   708      function_name = "${aws_lambda_function.my-func.arn}"
   709      principal = "sns.amazonaws.com"
   710      source_arn = "${aws_sns_topic.default.arn}"
   711  }
   712  
   713  resource "aws_sns_topic" "default" {
   714  	name = "tf-acc-user-updates-topic"
   715  }
   716  
   717  resource "aws_sns_topic_subscription" "lambda" {
   718      topic_arn = "${aws_sns_topic.default.arn}"
   719      protocol  = "lambda"
   720      endpoint  = "${aws_lambda_function.my-func.arn}"
   721  }
   722  
   723  resource "aws_lambda_function" "my-func" {
   724      filename = "test-fixtures/lambdatest.zip"
   725      function_name = "lambda_function_name_perm_sns"
   726      role = "${aws_iam_role.police.arn}"
   727      handler = "exports.handler"
   728      runtime = "nodejs4.3"
   729  }
   730  
   731  resource "aws_iam_role" "police" {
   732      name = "iam_for_lambda_perm_with_sns"
   733      assume_role_policy = <<EOF
   734  {
   735    "Version": "2012-10-17",
   736    "Statement": [
   737      {
   738        "Action": "sts:AssumeRole",
   739        "Principal": {
   740          "Service": "lambda.amazonaws.com"
   741        },
   742        "Effect": "Allow",
   743        "Sid": ""
   744      }
   745    ]
   746  }
   747  EOF
   748  }
   749  `
   750  
   751  var testAccAWSLambdaPermissionConfig_withIAMRole = `
   752  resource "aws_lambda_permission" "iam_role" {
   753      statement_id = "AllowExecutionFromIAMRole"
   754      action = "lambda:InvokeFunction"
   755      function_name = "${aws_lambda_function.my-func.arn}"
   756      principal = "${aws_iam_role.police.arn}"
   757  }
   758  
   759  resource "aws_lambda_function" "my-func" {
   760      filename = "test-fixtures/lambdatest.zip"
   761      function_name = "lambda_function_name_perm_iamrole"
   762      role = "${aws_iam_role.police.arn}"
   763      handler = "exports.handler"
   764      runtime = "nodejs4.3"
   765  }
   766  
   767  resource "aws_iam_role" "police" {
   768      name = "iam_for_lambda_perm_iamrole"
   769      assume_role_policy = <<EOF
   770  {
   771    "Version": "2012-10-17",
   772    "Statement": [
   773      {
   774        "Action": "sts:AssumeRole",
   775        "Principal": {
   776          "Service": "lambda.amazonaws.com"
   777        },
   778        "Effect": "Allow",
   779        "Sid": ""
   780      }
   781    ]
   782  }
   783  EOF
   784  }
   785  `
   786  
   787  var testLambdaPolicy = []byte(`{
   788  	"Version": "2012-10-17",
   789  	"Statement": [
   790  		{
   791  			"Condition": {
   792  				"StringEquals": {"AWS:SourceAccount": "319201112229"},
   793  				"ArnLike":{"AWS:SourceArn":"arn:aws:events:eu-west-1:319201112229:rule/RunDaily"}
   794  			},
   795  			"Action": "lambda:InvokeFunction",
   796  			"Resource": "arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction",
   797  			"Effect": "Allow",
   798  			"Principal": {"Service":"events.amazonaws.com"},
   799  			"Sid": "36fe77d9-a4ae-13fb-8beb-5dc6821d5291"
   800  		}
   801  	],
   802  	"Id":"default"
   803  }`)