Skip to content

Commit f5d5c02

Browse files
authored
Merge pull request #24220 from bnusunny/main
fixing error for creating additonal Lambda URLs on the same function
2 parents 8bde0a2 + ab0b097 commit f5d5c02

File tree

3 files changed

+96
-4
lines changed

3 files changed

+96
-4
lines changed

.changelog/24220.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
resource/aws_lambda_function_url: Ignore `ResourceConflictException` errors caused by existing `FunctionURLAllowPublicAccess` permission statements
3+
```

internal/service/lambda/function_url.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,19 @@ func resourceFunctionURLCreate(ctx context.Context, d *schema.ResourceData, meta
149149
StatementId: aws.String("FunctionURLAllowPublicAccess"),
150150
}
151151

152+
if qualifier != "" {
153+
input.Qualifier = aws.String(qualifier)
154+
}
155+
152156
log.Printf("[DEBUG] Adding Lambda Permission: %s", input)
153157
_, err := conn.AddPermissionWithContext(ctx, input)
154158

155159
if err != nil {
156-
return diag.Errorf("error adding Lambda Function URL (%s) permission %s", d.Id(), err)
160+
if tfawserr.ErrMessageContains(err, lambda.ErrCodeResourceConflictException, "The statement id (FunctionURLAllowPublicAccess) provided already exists") {
161+
log.Printf("[DEBUG] function permission statement 'FunctionURLAllowPublicAccess' already exists.")
162+
} else {
163+
return diag.Errorf("error adding Lambda Function URL (%s) permission %s", d.Id(), err)
164+
}
157165
}
158166
}
159167

internal/service/lambda/function_url_test.go

+84-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ import (
1717
)
1818

1919
func testAccFunctionURLPreCheck(t *testing.T) {
20-
if got, want := acctest.Partition(), endpoints.AwsPartitionID; got != want {
21-
t.Skipf("Lambda Function URLs are not supported in %s partition", got)
22-
}
20+
acctest.PreCheckPartition(endpoints.AwsPartitionID, t)
2321
}
2422

2523
func TestAccLambdaFunctionURL_basic(t *testing.T) {
@@ -155,6 +153,58 @@ func TestAccLambdaFunctionURL_Alias(t *testing.T) {
155153
})
156154
}
157155

156+
func TestAccLambdaFunctionURL_TwoURLs(t *testing.T) {
157+
var conf lambda.GetFunctionUrlConfigOutput
158+
latestResourceName := "aws_lambda_function_url.latest"
159+
liveResourceName := "aws_lambda_function_url.live"
160+
rString := sdkacctest.RandString(8)
161+
funcName := fmt.Sprintf("tf_acc_lambda_func_basic_%s", rString)
162+
aliasName := "live"
163+
policyName := fmt.Sprintf("tf_acc_policy_lambda_func_basic_%s", rString)
164+
roleName := fmt.Sprintf("tf_acc_role_lambda_func_basic_%s", rString)
165+
166+
resource.ParallelTest(t, resource.TestCase{
167+
PreCheck: func() { acctest.PreCheck(t); testAccFunctionURLPreCheck(t) },
168+
ErrorCheck: acctest.ErrorCheck(t, lambda.EndpointsID),
169+
Providers: acctest.Providers,
170+
CheckDestroy: testAccCheckFunctionURLDestroy,
171+
Steps: []resource.TestStep{
172+
{
173+
Config: testAccFunctionURLTwoURLsConfig(funcName, aliasName, policyName, roleName),
174+
Check: resource.ComposeAggregateTestCheckFunc(
175+
testAccCheckFunctionURLExists(latestResourceName, &conf),
176+
resource.TestCheckResourceAttr(latestResourceName, "authorization_type", lambda.FunctionUrlAuthTypeNone),
177+
resource.TestCheckResourceAttr(latestResourceName, "cors.#", "0"),
178+
resource.TestCheckResourceAttrSet(latestResourceName, "function_arn"),
179+
resource.TestCheckResourceAttr(latestResourceName, "function_name", funcName),
180+
resource.TestCheckResourceAttrSet(latestResourceName, "function_url"),
181+
resource.TestCheckResourceAttr(latestResourceName, "qualifier", ""),
182+
resource.TestCheckResourceAttrSet(latestResourceName, "url_id"),
183+
184+
testAccCheckFunctionURLExists(liveResourceName, &conf),
185+
resource.TestCheckResourceAttr(liveResourceName, "authorization_type", lambda.FunctionUrlAuthTypeNone),
186+
resource.TestCheckResourceAttr(liveResourceName, "cors.#", "0"),
187+
resource.TestCheckResourceAttrSet(liveResourceName, "function_arn"),
188+
resource.TestCheckResourceAttr(liveResourceName, "function_name", funcName),
189+
resource.TestCheckResourceAttrSet(liveResourceName, "function_url"),
190+
resource.TestCheckResourceAttr(liveResourceName, "qualifier", "live"),
191+
resource.TestCheckResourceAttrSet(liveResourceName, "url_id"),
192+
),
193+
},
194+
{
195+
ResourceName: latestResourceName,
196+
ImportState: true,
197+
ImportStateVerify: true,
198+
},
199+
{
200+
ResourceName: liveResourceName,
201+
ImportState: true,
202+
ImportStateVerify: true,
203+
},
204+
},
205+
})
206+
}
207+
158208
func testAccCheckFunctionURLExists(n string, v *lambda.GetFunctionUrlConfigOutput) resource.TestCheckFunc {
159209
return func(s *terraform.State) error {
160210
rs, ok := s.RootModule().Resources[n]
@@ -397,3 +447,34 @@ resource "aws_lambda_function_url" "test" {
397447
}
398448
`, funcName, aliasName))
399449
}
450+
451+
func testAccFunctionURLTwoURLsConfig(funcName, aliasName, policyName, roleName string) string {
452+
return acctest.ConfigCompose(testAccFunctionURLBaseConfig(policyName, roleName), fmt.Sprintf(`
453+
resource "aws_lambda_function" "test" {
454+
filename = "test-fixtures/lambdatest.zip"
455+
function_name = %[1]q
456+
role = aws_iam_role.iam_for_lambda.arn
457+
handler = "exports.example"
458+
runtime = "nodejs14.x"
459+
publish = true
460+
}
461+
462+
resource "aws_lambda_function_url" "latest" {
463+
function_name = aws_lambda_function.test.function_name
464+
authorization_type = "NONE"
465+
}
466+
467+
resource "aws_lambda_alias" "live" {
468+
name = %[2]q
469+
description = "a sample description"
470+
function_name = aws_lambda_function.test.function_name
471+
function_version = aws_lambda_function.test.version
472+
}
473+
474+
resource "aws_lambda_function_url" "live" {
475+
function_name = aws_lambda_function.test.function_name
476+
qualifier = aws_lambda_alias.live.name
477+
authorization_type = "NONE"
478+
}
479+
`, funcName, aliasName))
480+
}

0 commit comments

Comments
 (0)