Skip to content

Commit

Permalink
Merge pull request #26056 from bschaatsbergen/f/aws-alb-preserve-host…
Browse files Browse the repository at this point in the history
…-header

Add `preserve_host_header` argument to `aws_lb`
  • Loading branch information
ewbankkit authored Aug 1, 2022
2 parents 3b94d69 + f84896f commit 818e322
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 0 deletions.
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

0 comments on commit 818e322

Please sign in to comment.