Skip to content

Commit

Permalink
Merge pull request #34864 from dpirotte/f-aws-lb-connection-logs
Browse files Browse the repository at this point in the history
resource/aws_lb: Enable ALB connection logs
  • Loading branch information
ewbankkit committed Dec 12, 2023
2 parents 69c5bb0 + dc7fbe2 commit b2fe22d
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .changelog/34864.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_lb: Add `connection_logs` configuration block
```

```release-note:enhancement
data-source/aws_lb: Add `connection_logs` attribute
```
114 changes: 113 additions & 1 deletion internal/service/elbv2/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,35 @@ func ResourceLoadBalancer() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"connection_logs": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
DiffSuppressFunc: verify.SuppressMissingOptionalConfigurationBlock,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"bucket": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return !d.Get("connection_logs.0.enabled").(bool)
},
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"prefix": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return !d.Get("connection_logs.0.enabled").(bool)
},
},
},
},
},
"customer_owned_ipv4_pool": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -397,6 +426,17 @@ func resourceLoadBalancerCreate(ctx context.Context, d *schema.ResourceData, met
}
}

if lbType == elbv2.LoadBalancerTypeEnumApplication {
if v, ok := d.GetOk("connection_logs"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
attributes = append(attributes, expandLoadBalancerConnectionLogsAttributes(v.([]interface{})[0].(map[string]interface{}), false)...)
} else {
attributes = append(attributes, &elbv2.LoadBalancerAttribute{
Key: aws.String(loadBalancerAttributeConnectionLogsS3Enabled),
Value: flex.BoolValueToString(false),
})
}
}

attributes = append(attributes, loadBalancerAttributes.expand(d, false)...)

wait := false
Expand Down Expand Up @@ -459,7 +499,8 @@ func resourceLoadBalancerRead(ctx context.Context, d *schema.ResourceData, meta
d.Set("enforce_security_group_inbound_rules_on_private_link_traffic", lb.EnforceSecurityGroupInboundRulesOnPrivateLinkTraffic)
d.Set("internal", aws.StringValue(lb.Scheme) == elbv2.LoadBalancerSchemeEnumInternal)
d.Set("ip_address_type", lb.IpAddressType)
d.Set("load_balancer_type", lb.Type)
lbType := aws.StringValue(lb.Type)
d.Set("load_balancer_type", lbType)
d.Set("name", lb.LoadBalancerName)
d.Set("name_prefix", create.NamePrefixFromName(aws.StringValue(lb.LoadBalancerName)))
d.Set("security_groups", aws.StringValueSlice(lb.SecurityGroups))
Expand All @@ -482,6 +523,12 @@ func resourceLoadBalancerRead(ctx context.Context, d *schema.ResourceData, meta
return sdkdiag.AppendErrorf(diags, "setting access_logs: %s", err)
}

if lbType == elbv2.LoadBalancerTypeEnumApplication {
if err := d.Set("connection_logs", []interface{}{flattenLoadBalancerConnectionLogsAttributes(attributes)}); err != nil {
return sdkdiag.AppendErrorf(diags, "setting connection_logs: %s", err)
}
}

loadBalancerAttributes.flatten(d, attributes)

return diags
Expand All @@ -504,6 +551,17 @@ func resourceLoadBalancerUpdate(ctx context.Context, d *schema.ResourceData, met
}
}

if d.HasChange("connection_logs") {
if v, ok := d.GetOk("connection_logs"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
attributes = append(attributes, expandLoadBalancerConnectionLogsAttributes(v.([]interface{})[0].(map[string]interface{}), true)...)
} else {
attributes = append(attributes, &elbv2.LoadBalancerAttribute{
Key: aws.String(loadBalancerAttributeConnectionLogsS3Enabled),
Value: flex.BoolValueToString(false),
})
}
}

attributes = append(attributes, loadBalancerAttributes.expand(d, true)...)

if len(attributes) > 0 {
Expand Down Expand Up @@ -1195,6 +1253,39 @@ func expandLoadBalancerAccessLogsAttributes(tfMap map[string]interface{}, update
return apiObjects
}

func expandLoadBalancerConnectionLogsAttributes(tfMap map[string]interface{}, update bool) []*elbv2.LoadBalancerAttribute {
if tfMap == nil {
return nil
}

var apiObjects []*elbv2.LoadBalancerAttribute

if v, ok := tfMap["enabled"].(bool); ok {
apiObjects = append(apiObjects, &elbv2.LoadBalancerAttribute{
Key: aws.String(loadBalancerAttributeConnectionLogsS3Enabled),
Value: flex.BoolValueToString(v),
})

if v {
if v, ok := tfMap["bucket"].(string); ok && (update || v != "") {
apiObjects = append(apiObjects, &elbv2.LoadBalancerAttribute{
Key: aws.String(loadBalancerAttributeConnectionLogsS3Bucket),
Value: aws.String(v),
})
}

if v, ok := tfMap["prefix"].(string); ok && (update || v != "") {
apiObjects = append(apiObjects, &elbv2.LoadBalancerAttribute{
Key: aws.String(loadBalancerAttributeConnectionLogsS3Prefix),
Value: aws.String(v),
})
}
}
}

return apiObjects
}

func flattenLoadBalancerAccessLogsAttributes(apiObjects []*elbv2.LoadBalancerAttribute) map[string]interface{} {
if len(apiObjects) == 0 {
return nil
Expand All @@ -1216,6 +1307,27 @@ func flattenLoadBalancerAccessLogsAttributes(apiObjects []*elbv2.LoadBalancerAtt
return tfMap
}

func flattenLoadBalancerConnectionLogsAttributes(apiObjects []*elbv2.LoadBalancerAttribute) map[string]interface{} {
if len(apiObjects) == 0 {
return nil
}

tfMap := map[string]interface{}{}

for _, apiObject := range apiObjects {
switch k, v := aws.StringValue(apiObject.Key), apiObject.Value; k {
case loadBalancerAttributeConnectionLogsS3Enabled:
tfMap["enabled"] = flex.StringToBoolValue(v)
case loadBalancerAttributeConnectionLogsS3Bucket:
tfMap["bucket"] = aws.StringValue(v)
case loadBalancerAttributeConnectionLogsS3Prefix:
tfMap["prefix"] = aws.StringValue(v)
}
}

return tfMap
}

func expandSubnetMapping(tfMap map[string]interface{}) *elbv2.SubnetMapping {
if tfMap == nil {
return nil
Expand Down
24 changes: 24 additions & 0 deletions internal/service/elbv2/load_balancer_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ func DataSourceLoadBalancer() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"connection_logs": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"bucket": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"prefix": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"customer_owned_ipv4_pool": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -270,6 +290,10 @@ func dataSourceLoadBalancerRead(ctx context.Context, d *schema.ResourceData, met
return sdkdiag.AppendErrorf(diags, "setting access_logs: %s", err)
}

if err := d.Set("connection_logs", []interface{}{flattenLoadBalancerConnectionLogsAttributes(attributes)}); err != nil {
return sdkdiag.AppendErrorf(diags, "setting connection_logs: %s", err)
}

loadBalancerAttributes.flatten(d, attributes)

tags, err := listTags(ctx, conn, d.Id())
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 @@ -161,6 +161,7 @@ func TestAccELBV2LoadBalancerDataSource_backwardsCompatibility(t *testing.T) {
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.#"),
resource.TestCheckResourceAttrPair(dataSourceName1, "connection_logs.#", resourceName, "connection_logs.#"),
resource.TestCheckResourceAttrPair(dataSourceName2, "name", resourceName, "name"),
resource.TestCheckResourceAttrPair(dataSourceName2, "internal", resourceName, "internal"),
resource.TestCheckResourceAttrPair(dataSourceName2, "subnets.#", resourceName, "subnets.#"),
Expand All @@ -181,6 +182,7 @@ func TestAccELBV2LoadBalancerDataSource_backwardsCompatibility(t *testing.T) {
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.#"),
resource.TestCheckResourceAttrPair(dataSourceName2, "connection_logs.#", resourceName, "connection_logs.#"),
resource.TestCheckResourceAttrPair(dataSourceName3, "name", resourceName, "name"),
resource.TestCheckResourceAttrPair(dataSourceName3, "internal", resourceName, "internal"),
resource.TestCheckResourceAttrPair(dataSourceName3, "subnets.#", resourceName, "subnets.#"),
Expand All @@ -201,6 +203,7 @@ func TestAccELBV2LoadBalancerDataSource_backwardsCompatibility(t *testing.T) {
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.#"),
resource.TestCheckResourceAttrPair(dataSourceName3, "connection_logs.#", resourceName, "connection_logs.#"),
),
},
},
Expand Down

0 comments on commit b2fe22d

Please sign in to comment.