Skip to content

Commit 412cbb4

Browse files
authored
Merge pull request #41846 from drewtul/bug-attributes-sending
[Bug] Unconfigured listener attributes of `bool` type sent as `false`
2 parents bf29406 + 1c92dc1 commit 412cbb4

File tree

3 files changed

+130
-3
lines changed

3 files changed

+130
-3
lines changed

.changelog/41846.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
resource/aws_lb_listener: Don't send zero value (`false`, `0` or `""`) for unconfigured listener attributes on Create
3+
```

internal/service/elbv2/listener.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -971,9 +971,16 @@ func (m listenerAttributeMap) expand(d *schema.ResourceData, listenerType awstyp
971971
var apiObjects []awstypes.ListenerAttribute
972972

973973
for tfAttributeName, attributeInfo := range m {
974-
// Skip if an update and the attribute hasn't changed.
975-
if update && !d.HasChange(tfAttributeName) {
976-
continue
974+
if update {
975+
if !d.HasChange(tfAttributeName) {
976+
// Skip if an update and the attribute hasn't changed.
977+
continue
978+
}
979+
} else {
980+
if v := d.GetRawConfig().GetAttr(tfAttributeName); !v.IsKnown() || v.IsNull() {
981+
// Skip if a create and the attribute isn't configured.
982+
continue
983+
}
977984
}
978985

979986
// Not all attributes are supported on all listener types.

internal/service/elbv2/listener_test.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,70 @@ func TestAccELBV2Listener_attributes_alb_HTTPRequestHeaders(t *testing.T) {
12481248
})
12491249
}
12501250

1251+
func TestAccELBV2Listener_attributes_alb_HTTPRequestPartialHeaders(t *testing.T) {
1252+
ctx := acctest.Context(t)
1253+
var conf awstypes.Listener
1254+
resourceName := "aws_lb_listener.test"
1255+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
1256+
1257+
resource.ParallelTest(t, resource.TestCase{
1258+
PreCheck: func() { acctest.PreCheck(ctx, t) },
1259+
ErrorCheck: acctest.ErrorCheck(t, names.ELBV2ServiceID),
1260+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
1261+
CheckDestroy: testAccCheckListenerDestroy(ctx),
1262+
Steps: []resource.TestStep{
1263+
{
1264+
Config: testAccListenerConfig_attributes_albHTTPRequestPartialHeaders(rName, "https://example.com", "DENY"),
1265+
Check: resource.ComposeAggregateTestCheckFunc(
1266+
testAccCheckListenerExists(ctx, resourceName, &conf),
1267+
resource.TestCheckResourceAttrPair(resourceName, "load_balancer_arn", "aws_lb.test", names.AttrARN),
1268+
resource.TestCheckResourceAttr(resourceName, names.AttrProtocol, "HTTP"),
1269+
resource.TestCheckResourceAttr(resourceName, names.AttrPort, "80"),
1270+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_server_enabled", acctest.CtTrue),
1271+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_strict_transport_security_header_value", "max-age=31536000; includeSubDomains"),
1272+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_origin_header_value", "https://example.com"),
1273+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_methods_header_value", "GET,POST,OPTIONS"),
1274+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_headers_header_value", "Content-Type,X-Custom-Header"),
1275+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_credentials_header_value", acctest.CtTrue),
1276+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_expose_headers_header_value", "X-Custom-Header"),
1277+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_max_age_header_value", "3600"),
1278+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_content_security_policy_header_value", "default-src 'self'"),
1279+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_x_content_type_options_header_value", "nosniff"),
1280+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_x_frame_options_header_value", "DENY"),
1281+
),
1282+
},
1283+
{
1284+
ResourceName: resourceName,
1285+
ImportState: true,
1286+
ImportStateVerify: true,
1287+
ImportStateVerifyIgnore: []string{
1288+
"default_action.0.forward",
1289+
},
1290+
},
1291+
{
1292+
Config: testAccListenerConfig_attributes_albHTTPRequestPartialHeaders(rName, "https://www.example.com", "SAMEORIGIN"),
1293+
Check: resource.ComposeAggregateTestCheckFunc(
1294+
testAccCheckListenerExists(ctx, resourceName, &conf),
1295+
resource.TestCheckResourceAttrPair(resourceName, "load_balancer_arn", "aws_lb.test", names.AttrARN),
1296+
resource.TestCheckResourceAttr(resourceName, names.AttrProtocol, "HTTP"),
1297+
resource.TestCheckResourceAttr(resourceName, names.AttrPort, "80"),
1298+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_server_enabled", acctest.CtTrue),
1299+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_strict_transport_security_header_value", "max-age=31536000; includeSubDomains"),
1300+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_origin_header_value", "https://www.example.com"),
1301+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_methods_header_value", "GET,POST,OPTIONS"),
1302+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_headers_header_value", "Content-Type,X-Custom-Header"),
1303+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_allow_credentials_header_value", acctest.CtTrue),
1304+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_expose_headers_header_value", "X-Custom-Header"),
1305+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_access_control_max_age_header_value", "3600"),
1306+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_content_security_policy_header_value", "default-src 'self'"),
1307+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_x_content_type_options_header_value", "nosniff"),
1308+
resource.TestCheckResourceAttr(resourceName, "routing_http_response_x_frame_options_header_value", "SAMEORIGIN"),
1309+
),
1310+
},
1311+
},
1312+
})
1313+
}
1314+
12511315
func TestAccELBV2Listener_attributes_alb_HTTPSRequestHeaders(t *testing.T) {
12521316
ctx := acctest.Context(t)
12531317
var conf awstypes.Listener
@@ -3312,6 +3376,59 @@ resource "aws_lb_target_group" "test" {
33123376
`, rName, allowOriginHeaderValue, frameOptionsHeaderValue))
33133377
}
33143378

3379+
func testAccListenerConfig_attributes_albHTTPRequestPartialHeaders(rName, allowOriginHeaderValue, frameOptionsHeaderValue string) string {
3380+
return acctest.ConfigCompose(
3381+
testAccListenerConfig_base(rName), fmt.Sprintf(`
3382+
resource "aws_lb_listener" "test" {
3383+
load_balancer_arn = aws_lb.test.arn
3384+
protocol = "HTTP"
3385+
port = 80
3386+
3387+
routing_http_response_strict_transport_security_header_value = "max-age=31536000; includeSubDomains"
3388+
routing_http_response_access_control_allow_origin_header_value = %[2]q
3389+
routing_http_response_access_control_allow_methods_header_value = "GET,POST,OPTIONS"
3390+
routing_http_response_access_control_allow_headers_header_value = "Content-Type,X-Custom-Header"
3391+
routing_http_response_access_control_allow_credentials_header_value = "true"
3392+
routing_http_response_access_control_expose_headers_header_value = "X-Custom-Header"
3393+
routing_http_response_access_control_max_age_header_value = "3600"
3394+
routing_http_response_content_security_policy_header_value = "default-src 'self'"
3395+
routing_http_response_x_content_type_options_header_value = "nosniff"
3396+
routing_http_response_x_frame_options_header_value = %[3]q
3397+
3398+
default_action {
3399+
type = "forward"
3400+
target_group_arn = aws_lb_target_group.test.arn
3401+
}
3402+
}
3403+
3404+
resource "aws_lb" "test" {
3405+
name = %[1]q
3406+
internal = true
3407+
load_balancer_type = "application"
3408+
security_groups = [aws_security_group.test.id]
3409+
subnets = aws_subnet.test[*].id
3410+
3411+
idle_timeout = 30
3412+
enable_deletion_protection = false
3413+
3414+
tags = {
3415+
Name = %[1]q
3416+
}
3417+
}
3418+
3419+
resource "aws_lb_target_group" "test" {
3420+
name = %[1]q
3421+
port = 80
3422+
protocol = "HTTP"
3423+
vpc_id = aws_vpc.test.id
3424+
3425+
tags = {
3426+
Name = %[1]q
3427+
}
3428+
}
3429+
`, rName, allowOriginHeaderValue, frameOptionsHeaderValue))
3430+
}
3431+
33153432
func testAccListenerConfig_attributes_albHTTPSRequestHeaders(rName, key, certificate string) string {
33163433
return acctest.ConfigCompose(
33173434
testAccListenerConfig_base(rName), fmt.Sprintf(`

0 commit comments

Comments
 (0)