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

resource/aws_lb_listener: Mark port argument as optional and only default protocol argument to HTTP for Application Load Balancers (Support Gateway Load Balancer) #16306

Merged
merged 2 commits into from
Nov 25, 2020
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
2 changes: 2 additions & 0 deletions .github/workflows/website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ jobs:
"--disable-rule=aws_iam_saml_provider_invalid_saml_metadata_document"
"--disable-rule=aws_iam_server_certificate_invalid_certificate_body"
"--disable-rule=aws_iam_server_certificate_invalid_private_key"
"--disable-rule=aws_lb_invalid_load_balancer_type"
"--disable-rule=aws_lb_target_group_invalid_protocol"
"--disable-rule=aws_transfer_ssh_key_invalid_body"
"--disable-rule=aws_worklink_website_certificate_authority_association_invalid_certificate"
)
Expand Down
36 changes: 22 additions & 14 deletions aws/resource_aws_lb_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,18 @@ func resourceAwsLbListener() *schema.Resource {

"port": {
Type: schema.TypeInt,
Required: true,
Optional: true,
ValidateFunc: validation.IntBetween(1, 65535),
},

"protocol": {
Type: schema.TypeString,
Optional: true,
Default: "HTTP",
Computed: true,
StateFunc: func(v interface{}) string {
return strings.ToUpper(v.(string))
},
ValidateFunc: validation.StringInSlice([]string{
elbv2.ProtocolEnumHttp,
elbv2.ProtocolEnumHttps,
elbv2.ProtocolEnumTcp,
elbv2.ProtocolEnumTls,
elbv2.ProtocolEnumUdp,
elbv2.ProtocolEnumTcpUdp,
}, true),
ValidateFunc: validation.StringInSlice(elbv2.ProtocolEnum_Values(), true),
},

"ssl_policy": {
Expand Down Expand Up @@ -392,8 +385,17 @@ func resourceAwsLbListenerCreate(d *schema.ResourceData, meta interface{}) error

params := &elbv2.CreateListenerInput{
LoadBalancerArn: aws.String(lbArn),
Port: aws.Int64(int64(d.Get("port").(int))),
Protocol: aws.String(d.Get("protocol").(string)),
}

if v, ok := d.GetOk("port"); ok {
params.Port = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("protocol"); ok {
params.Protocol = aws.String(v.(string))
} else if strings.Contains(lbArn, "loadbalancer/app/") {
// Keep previous default of HTTP for Application Load Balancers
params.Protocol = aws.String(elbv2.ProtocolEnumHttp)
}

if sslPolicy, ok := d.GetOk("ssl_policy"); ok {
Expand Down Expand Up @@ -744,8 +746,14 @@ func resourceAwsLbListenerUpdate(d *schema.ResourceData, meta interface{}) error

params := &elbv2.ModifyListenerInput{
ListenerArn: aws.String(d.Id()),
Port: aws.Int64(int64(d.Get("port").(int))),
Protocol: aws.String(d.Get("protocol").(string)),
}

if v, ok := d.GetOk("port"); ok {
params.Port = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("protocol"); ok {
params.Protocol = aws.String(v.(string))
}

if sslPolicy, ok := d.GetOk("ssl_policy"); ok {
Expand Down
79 changes: 78 additions & 1 deletion aws/resource_aws_lb_listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,30 @@ func TestAccAWSLBListener_https(t *testing.T) {
})
}

func TestAccAWSLBListener_LoadBalancerArn_GatewayLoadBalancer(t *testing.T) {
var conf elbv2.Listener
rName := acctest.RandomWithPrefix("tf-acc-test")
lbResourceName := "aws_lb.test"
resourceName := "aws_lb_listener.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSLBListenerDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSLBListenerConfig_LoadBalancerArn_GatewayLoadBalancer(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSLBListenerExists(resourceName, &conf),
resource.TestCheckResourceAttrPair(resourceName, "load_balancer_arn", lbResourceName, "arn"),
resource.TestCheckResourceAttr(resourceName, "protocol", ""),
resource.TestCheckResourceAttr(resourceName, "port", "0"),
),
},
},
})
}

func TestAccAWSLBListener_Protocol_Tls(t *testing.T) {
var listener1 elbv2.Listener
key := tlsRsaPrivateKeyPem(2048)
Expand Down Expand Up @@ -528,7 +552,6 @@ func testAccAWSLBListenerConfig_basic(lbName, targetGroupName string) string {
return fmt.Sprintf(`
resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.alb_test.id
protocol = "HTTP"
port = "80"

default_action {
Expand Down Expand Up @@ -1336,6 +1359,60 @@ resource "aws_iam_server_certificate" "test_cert" {
`, rName, tlsPemEscapeNewlines(certificate), tlsPemEscapeNewlines(key))
}

func testAccAWSLBListenerConfig_LoadBalancerArn_GatewayLoadBalancer(rName string) string {
return composeConfig(
testAccAvailableAZsNoOptInConfig(),
fmt.Sprintf(`
resource "aws_vpc" "test" {
cidr_block = "10.10.10.0/25"

tags = {
Name = "tf-acc-test-load-balancer"
}
}

resource "aws_subnet" "test" {
availability_zone = data.aws_availability_zones.available.names[0]
cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 2, 0)
vpc_id = aws_vpc.test.id

tags = {
Name = "tf-acc-test-load-balancer"
}
}

resource "aws_lb" "test" {
load_balancer_type = "gateway"
name = %[1]q

subnet_mapping {
subnet_id = aws_subnet.test.id
}
}

resource "aws_lb_target_group" "test" {
name = %[1]q
port = 6081
protocol = "GENEVE"
vpc_id = aws_vpc.test.id

health_check {
port = 80
protocol = "HTTP"
}
}

resource "aws_lb_listener" "test" {
load_balancer_arn = aws_lb.test.id

default_action {
target_group_arn = aws_lb_target_group.test.id
type = "forward"
}
}
`, rName))
}

func testAccAWSLBListenerConfig_Protocol_Tls(rName, key, certificate string) string {
return fmt.Sprintf(`
data "aws_availability_zones" "available" {
Expand Down
37 changes: 35 additions & 2 deletions website/docs/r/lb_listener.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,47 @@ resource "aws_lb_listener" "front_end" {
}
```

### Gateway Load Balancer Listener

```hcl
resource "aws_lb" "example" {
load_balancer_type = "gateway"
name = "example"

subnet_mapping {
subnet_id = aws_subnet.example.id
}
}

resource "aws_lb_target_group" "example" {
name = "example"
port = 6081
protocol = "GENEVE"
vpc_id = aws_vpc.example.id

health_check {
port = 80
protocol = "HTTP"
}
}

resource "aws_lb_listener" "example" {
load_balancer_arn = aws_lb.example.id

default_action {
target_group_arn = aws_lb_target_group.example.id
type = "forward"
}
}
```

## Argument Reference

The following arguments are supported:

* `load_balancer_arn` - (Required, Forces New Resource) The ARN of the load balancer.
* `port` - (Required) The port on which the load balancer is listening.
* `protocol` - (Optional) The protocol for connections from clients to the load balancer. Valid values are `TCP`, `TLS`, `UDP`, `TCP_UDP`, `HTTP` and `HTTPS`. Defaults to `HTTP`.
* `port` - (Optional) The port on which the load balancer is listening. Not valid for Gateway Load Balancers.
* `protocol` - (Optional) The protocol for connections from clients to the load balancer. For Application Load Balancers, valid values are `HTTP` and `HTTPS`, with a default of `HTTP`. For Network Load Balancers, valid values are `TCP`, `TLS`, `UDP`, and `TCP_UDP`. Not valid to use `UDP` or `TCP_UDP` if dual-stack mode is enabled. Not valid for Gateway Load Balancers.
* `ssl_policy` - (Optional) The name of the SSL Policy for the listener. Required if `protocol` is `HTTPS` or `TLS`.
* `certificate_arn` - (Optional) The ARN of the default SSL server certificate. Exactly one certificate is required if the protocol is HTTPS. For adding additional SSL certificates, see the [`aws_lb_listener_certificate` resource](/docs/providers/aws/r/lb_listener_certificate.html).
* `default_action` - (Required) An Action block. Action blocks are documented below.
Expand Down