Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preserve_host_header argument to aws_lb #26056

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/26056.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_lb: Add `preserve_host_header` argument
```

```release-note:enhancement
data-source/aws_lb: Add `preserve_host_header` attribute
```
18 changes: 18 additions & 0 deletions internal/service/elbv2/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ func ResourceLoadBalancer() *schema.Resource {
DiffSuppressFunc: suppressIfLBType("network"),
},

"preserve_host_header": {
Type: schema.TypeBool,
Optional: true,
Default: false,
DiffSuppressFunc: suppressIfLBTypeNot(elbv2.LoadBalancerTypeEnumApplication),
},

"enable_cross_zone_load_balancing": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -502,6 +509,13 @@ func resourceLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error
})
}

if d.HasChange("preserve_host_header") || d.IsNewResource() {
attributes = append(attributes, &elbv2.LoadBalancerAttribute{
Key: aws.String("routing.http.preserve_host_header.enabled"),
Value: aws.String(strconv.FormatBool(d.Get("preserve_host_header").(bool))),
})
}

if d.HasChange("desync_mitigation_mode") || d.IsNewResource() {
attributes = append(attributes, &elbv2.LoadBalancerAttribute{
Key: aws.String("routing.http.desync_mitigation_mode"),
Expand Down Expand Up @@ -885,6 +899,10 @@ func flattenResource(d *schema.ResourceData, meta interface{}, lb *elbv2.LoadBal
dropInvalidHeaderFieldsEnabled := aws.StringValue(attr.Value) == "true"
log.Printf("[DEBUG] Setting LB Invalid Header Fields Enabled: %t", dropInvalidHeaderFieldsEnabled)
d.Set("drop_invalid_header_fields", dropInvalidHeaderFieldsEnabled)
case "routing.http.preserve_host_header.enabled":
preserveHostHeaderEnabled := aws.StringValue(attr.Value) == "true"
log.Printf("[DEBUG] Setting LB Preserve Host Header Enabled: %t", preserveHostHeaderEnabled)
d.Set("preserve_host_header", preserveHostHeaderEnabled)
case "deletion_protection.enabled":
protectionEnabled := aws.StringValue(attr.Value) == "true"
log.Printf("[DEBUG] Setting LB Deletion Protection Enabled: %t", protectionEnabled)
Expand Down
8 changes: 8 additions & 0 deletions internal/service/elbv2/load_balancer_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ func DataSourceLoadBalancer() *schema.Resource {
Computed: true,
},

"preserve_host_header": {
Type: schema.TypeBool,
Computed: true,
},

"vpc_id": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -282,6 +287,9 @@ func dataSourceLoadBalancerRead(d *schema.ResourceData, meta interface{}) error
case "routing.http.drop_invalid_header_fields.enabled":
dropInvalidHeaderFieldsEnabled := aws.StringValue(attr.Value) == "true"
d.Set("drop_invalid_header_fields", dropInvalidHeaderFieldsEnabled)
case "routing.http.preserve_host_header.enabled":
preserveHostHeaderEnabled := aws.StringValue(attr.Value) == "true"
d.Set("preserve_host_header", preserveHostHeaderEnabled)
case "deletion_protection.enabled":
protectionEnabled := aws.StringValue(attr.Value) == "true"
d.Set("enable_deletion_protection", protectionEnabled)
Expand Down
3 changes: 3 additions & 0 deletions internal/service/elbv2/load_balancer_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ func TestAccELBV2LoadBalancerDataSource_backwardsCompatibility(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName1, "ip_address_type", resourceName, "ip_address_type"),
resource.TestCheckResourceAttrPair(dataSourceName1, "subnet_mapping.#", resourceName, "subnet_mapping.#"),
resource.TestCheckResourceAttrPair(dataSourceName1, "drop_invalid_header_fields", resourceName, "drop_invalid_header_fields"),
resource.TestCheckResourceAttrPair(dataSourceName1, "preserve_host_header", resourceName, "preserve_host_header"),
resource.TestCheckResourceAttrPair(dataSourceName1, "enable_http2", resourceName, "enable_http2"),
resource.TestCheckResourceAttrPair(dataSourceName1, "enable_waf_fail_open", resourceName, "enable_waf_fail_open"),
resource.TestCheckResourceAttrPair(dataSourceName1, "access_logs.#", resourceName, "access_logs.#"),
Expand All @@ -164,6 +165,7 @@ func TestAccELBV2LoadBalancerDataSource_backwardsCompatibility(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName2, "ip_address_type", resourceName, "ip_address_type"),
resource.TestCheckResourceAttrPair(dataSourceName2, "subnet_mapping.#", resourceName, "subnet_mapping.#"),
resource.TestCheckResourceAttrPair(dataSourceName2, "drop_invalid_header_fields", resourceName, "drop_invalid_header_fields"),
resource.TestCheckResourceAttrPair(dataSourceName2, "preserve_host_header", resourceName, "preserve_host_header"),
resource.TestCheckResourceAttrPair(dataSourceName2, "enable_http2", resourceName, "enable_http2"),
resource.TestCheckResourceAttrPair(dataSourceName2, "enable_waf_fail_open", resourceName, "enable_waf_fail_open"),
resource.TestCheckResourceAttrPair(dataSourceName2, "access_logs.#", resourceName, "access_logs.#"),
Expand All @@ -183,6 +185,7 @@ func TestAccELBV2LoadBalancerDataSource_backwardsCompatibility(t *testing.T) {
resource.TestCheckResourceAttrPair(dataSourceName3, "ip_address_type", resourceName, "ip_address_type"),
resource.TestCheckResourceAttrPair(dataSourceName3, "subnet_mapping.#", resourceName, "subnet_mapping.#"),
resource.TestCheckResourceAttrPair(dataSourceName3, "drop_invalid_header_fields", resourceName, "drop_invalid_header_fields"),
resource.TestCheckResourceAttrPair(dataSourceName3, "preserve_host_header", resourceName, "preserve_host_header"),
resource.TestCheckResourceAttrPair(dataSourceName3, "enable_http2", resourceName, "enable_http2"),
resource.TestCheckResourceAttrPair(dataSourceName3, "enable_waf_fail_open", resourceName, "enable_waf_fail_open"),
resource.TestCheckResourceAttrPair(dataSourceName3, "access_logs.#", resourceName, "access_logs.#"),
Expand Down
113 changes: 113 additions & 0 deletions internal/service/elbv2/load_balancer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,50 @@ func TestAccELBV2LoadBalancer_ApplicationLoadBalancer_updateDropInvalidHeaderFie
})
}

func TestAccELBV2LoadBalancer_ApplicationLoadBalancer_updatePreserveHostHeader(t *testing.T) {
var pre, mid, post elbv2.LoadBalancer
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

if testing.Short() {
t.Skip("skipping long-running test in short mode")
}

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, elbv2.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckLoadBalancerDestroy,
Steps: []resource.TestStep{
{
Config: testAccLoadBalancerConfig_enablePreserveHostHeader(rName, false),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckLoadBalancerExists("aws_lb.lb_test", &pre),
testAccCheckLoadBalancerAttribute("aws_lb.lb_test", "routing.http.preserve_host_header.enabled", "false"),
resource.TestCheckResourceAttr("aws_lb.lb_test", "preserve_host_header", "false"),
),
},
{
Config: testAccLoadBalancerConfig_enablePreserveHostHeader(rName, true),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckLoadBalancerExists("aws_lb.lb_test", &mid),
testAccCheckLoadBalancerAttribute("aws_lb.lb_test", "routing.http.preserve_host_header.enabled", "true"),
resource.TestCheckResourceAttr("aws_lb.lb_test", "preserve_host_header", "true"),
testAccChecklbARNs(&pre, &mid),
),
},
{
Config: testAccLoadBalancerConfig_enablePreserveHostHeader(rName, false),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckLoadBalancerExists("aws_lb.lb_test", &post),
testAccCheckLoadBalancerAttribute("aws_lb.lb_test", "routing.http.preserve_host_header.enabled", "false"),
resource.TestCheckResourceAttr("aws_lb.lb_test", "preserve_host_header", "false"),
testAccChecklbARNs(&mid, &post),
),
},
},
})
}

func TestAccELBV2LoadBalancer_ApplicationLoadBalancer_updateDeletionProtection(t *testing.T) {
var pre, mid, post elbv2.LoadBalancer
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
Expand Down Expand Up @@ -1903,6 +1947,75 @@ resource "aws_security_group" "alb_test" {
`, rName, dropInvalid))
}

func testAccLoadBalancerConfig_enablePreserveHostHeader(rName string, enablePreserveHostHeader bool) string {
return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(`
resource "aws_lb" "lb_test" {
name = %[1]q
internal = true
security_groups = [aws_security_group.alb_test.id]
subnets = aws_subnet.alb_test[*].id

idle_timeout = 30
enable_deletion_protection = false

preserve_host_header = %[2]t

tags = {
Name = %[1]q
}
}

variable "subnets" {
default = ["10.0.1.0/24", "10.0.2.0/24"]
type = list(string)
}

resource "aws_vpc" "alb_test" {
cidr_block = "10.0.0.0/16"

tags = {
Name = %[1]q
}
}

resource "aws_subnet" "alb_test" {
count = 2
vpc_id = aws_vpc.alb_test.id
cidr_block = element(var.subnets, count.index)
map_public_ip_on_launch = true
availability_zone = element(data.aws_availability_zones.available.names, count.index)

tags = {
Name = "tf-acc-lb-basic-${count.index}"
}
}

resource "aws_security_group" "alb_test" {
name = "allow_all_alb_test"
description = "Used for ALB Testing"
vpc_id = aws_vpc.alb_test.id

ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
Name = %[1]q
}
}
`, rName, enablePreserveHostHeader))
}

func testAccLoadBalancerConfig_enableDeletionProtection(rName string, deletionProtection bool) string {
return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(`
resource "aws_lb" "lb_test" {
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/lb.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Terraform will autogenerate a name beginning with `tf-lb`.
* `load_balancer_type` - (Optional) The type of load balancer to create. Possible values are `application`, `gateway`, or `network`. The default value is `application`.
* `security_groups` - (Optional) A list of security group IDs to assign to the LB. Only valid for Load Balancers of type `application`.
* `drop_invalid_header_fields` - (Optional) Indicates whether HTTP headers with header fields that are not valid are removed by the load balancer (true) or routed to targets (false). The default is false. Elastic Load Balancing requires that message header names contain only alphanumeric characters and hyphens. Only valid for Load Balancers of type `application`.
* `preserve_host_header` - (Optional) Indicates whether the Application Load Balancer should preserve the Host header in the HTTP request and send it to the target without any change. Defaults to `false`.
* `access_logs` - (Optional) An Access Logs block. Access Logs documented below.
* `subnets` - (Optional) A list of subnet IDs to attach to the LB. Subnets
cannot be updated for Load Balancers of type `network`. Changing this value
Expand Down