Skip to content

Commit 9da37d3

Browse files
authored
Merge pull request #45271 from tabito-hara/f-aws_vpn_connection-add_bgp_log
[Enhancement] aws_vpn_connection: Support Site-to-Site VPN BGP logging
2 parents 71deb9d + 4ca5874 commit 9da37d3

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

.changelog/45271.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
resource/aws_vpn_connection: Add `bgp_log_enabled`, `bgp_log_group_arn`, and `bgp_log_stream_arn` arguments to `tunnel1_log_options.cloudwatch_log_options` and `tunnel2_log_options.cloudwatch_log_options` blocks
3+
```

internal/service/ec2/consts.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,18 @@ func vpnTunnelCloudWatchLogOutputFormat_Values() []string {
163163
}
164164
}
165165

166+
const (
167+
vpnTunnelCloudWatchLogBGPLogOutputFormatJSON = names.AttrJSON
168+
vpnTunnelCloudWatchLogBGPLogOutputFormatText = "text"
169+
)
170+
171+
func vpnTunnelCloudWatchLogBGPLogOutputFormat_Values() []string {
172+
return []string{
173+
vpnTunnelCloudWatchLogBGPLogOutputFormatJSON,
174+
vpnTunnelCloudWatchLogBGPLogOutputFormatText,
175+
}
176+
}
177+
166178
const (
167179
vpnTunnelOptionsPhase1EncryptionAlgorithmAES128 = "AES128"
168180
vpnTunnelOptionsPhase1EncryptionAlgorithmAES256 = "AES256"

internal/service/ec2/vpnsite_connection.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,19 @@ func resourceVPNConnection() *schema.Resource {
248248
MaxItems: 1,
249249
Elem: &schema.Resource{
250250
Schema: map[string]*schema.Schema{
251+
"bgp_log_enabled": {
252+
Type: schema.TypeBool,
253+
Optional: true,
254+
},
255+
"bgp_log_group_arn": {
256+
Type: schema.TypeString,
257+
Optional: true,
258+
},
259+
"bgp_log_output_format": {
260+
Type: schema.TypeString,
261+
Optional: true,
262+
ValidateFunc: validation.StringInSlice(vpnTunnelCloudWatchLogBGPLogOutputFormat_Values(), false),
263+
},
251264
"log_enabled": {
252265
Type: schema.TypeBool,
253266
Optional: true,
@@ -464,6 +477,19 @@ func resourceVPNConnection() *schema.Resource {
464477
MaxItems: 1,
465478
Elem: &schema.Resource{
466479
Schema: map[string]*schema.Schema{
480+
"bgp_log_enabled": {
481+
Type: schema.TypeBool,
482+
Optional: true,
483+
},
484+
"bgp_log_group_arn": {
485+
Type: schema.TypeString,
486+
Optional: true,
487+
},
488+
"bgp_log_output_format": {
489+
Type: schema.TypeString,
490+
Optional: true,
491+
ValidateFunc: validation.StringInSlice(vpnTunnelCloudWatchLogBGPLogOutputFormat_Values(), false),
492+
},
467493
"log_enabled": {
468494
Type: schema.TypeBool,
469495
Optional: true,
@@ -1177,6 +1203,21 @@ func expandCloudWatchLogOptionsSpecification(tfMap map[string]any) *awstypes.Clo
11771203

11781204
apiObject := &awstypes.CloudWatchLogOptionsSpecification{}
11791205

1206+
if v, ok := tfMap["bgp_log_enabled"].(bool); ok {
1207+
apiObject.BgpLogEnabled = aws.Bool(v)
1208+
}
1209+
1210+
// No ARN or format if not enabled.
1211+
if aws.ToBool(apiObject.BgpLogEnabled) {
1212+
if v, ok := tfMap["bgp_log_group_arn"].(string); ok && v != "" {
1213+
apiObject.BgpLogGroupArn = aws.String(v)
1214+
}
1215+
1216+
if v, ok := tfMap["bgp_log_output_format"].(string); ok && v != "" {
1217+
apiObject.BgpLogOutputFormat = aws.String(v)
1218+
}
1219+
}
1220+
11801221
if v, ok := tfMap["log_enabled"].(bool); ok {
11811222
apiObject.LogEnabled = aws.Bool(v)
11821223
}
@@ -1525,6 +1566,22 @@ func flattenCloudWatchLogOptions(apiObject *awstypes.CloudWatchLogOptions) map[s
15251566

15261567
tfMap := map[string]any{}
15271568

1569+
if v := apiObject.BgpLogEnabled; v != nil {
1570+
enabled := aws.ToBool(v)
1571+
tfMap["bgp_log_enabled"] = enabled
1572+
1573+
// No ARN or format if not enabled.
1574+
if enabled {
1575+
if v := apiObject.BgpLogGroupArn; v != nil {
1576+
tfMap["bgp_log_group_arn"] = aws.ToString(v)
1577+
}
1578+
1579+
if v := apiObject.BgpLogOutputFormat; v != nil {
1580+
tfMap["bgp_log_output_format"] = aws.ToString(v)
1581+
}
1582+
}
1583+
}
1584+
15281585
if v := apiObject.LogEnabled; v != nil {
15291586
enabled := aws.ToBool(v)
15301587
tfMap["log_enabled"] = enabled

internal/service/ec2/vpnsite_connection_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,56 @@ func TestAccSiteVPNConnection_cloudWatchLogOptions(t *testing.T) {
400400
})
401401
}
402402

403+
func TestAccSiteVPNConnection_cloudWatchLogOptionsBGPLog(t *testing.T) {
404+
ctx := acctest.Context(t)
405+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
406+
rBgpAsn := sdkacctest.RandIntRange(64512, 65534)
407+
resourceName := "aws_vpn_connection.test"
408+
var vpn awstypes.VpnConnection
409+
410+
resource.ParallelTest(t, resource.TestCase{
411+
PreCheck: func() { acctest.PreCheck(ctx, t) },
412+
ErrorCheck: acctest.ErrorCheck(t, names.EC2ServiceID),
413+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
414+
CheckDestroy: testAccCheckVPNConnectionDestroy(ctx),
415+
Steps: []resource.TestStep{
416+
{
417+
Config: testAccVPNConnectionConfig_cloudWatchLogOptionsBGPLog(rName, rBgpAsn),
418+
Check: resource.ComposeAggregateTestCheckFunc(
419+
testAccVPNConnectionExists(ctx, resourceName, &vpn),
420+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.#", "1"),
421+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.0.cloudwatch_log_options.#", "1"),
422+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.0.cloudwatch_log_options.0.bgp_log_enabled", acctest.CtTrue),
423+
resource.TestCheckResourceAttrPair(resourceName, "tunnel1_log_options.0.cloudwatch_log_options.0.bgp_log_group_arn", "aws_cloudwatch_log_group.test", names.AttrARN),
424+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.0.cloudwatch_log_options.0.bgp_log_output_format", names.AttrJSON),
425+
resource.TestCheckResourceAttr(resourceName, "tunnel2_log_options.#", "1"),
426+
resource.TestCheckResourceAttr(resourceName, "tunnel2_log_options.0.cloudwatch_log_options.#", "1"),
427+
resource.TestCheckResourceAttr(resourceName, "tunnel2_log_options.0.cloudwatch_log_options.0.bgp_log_enabled", acctest.CtFalse),
428+
),
429+
},
430+
{
431+
ResourceName: resourceName,
432+
ImportState: true,
433+
ImportStateVerify: true,
434+
ImportStateVerifyIgnore: []string{"vgw_telemetry"},
435+
},
436+
{
437+
Config: testAccVPNConnectionConfig_cloudWatchLogOptionsBGPLogUpdated(rName, rBgpAsn),
438+
Check: resource.ComposeAggregateTestCheckFunc(
439+
testAccVPNConnectionExists(ctx, resourceName, &vpn),
440+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.#", "1"),
441+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.0.cloudwatch_log_options.#", "1"),
442+
resource.TestCheckResourceAttr(resourceName, "tunnel1_log_options.0.cloudwatch_log_options.0.bgp_log_enabled", acctest.CtFalse),
443+
resource.TestCheckResourceAttr(resourceName, "tunnel2_log_options.#", "1"),
444+
resource.TestCheckResourceAttr(resourceName, "tunnel2_log_options.0.cloudwatch_log_options.0.bgp_log_enabled", acctest.CtTrue),
445+
resource.TestCheckResourceAttrPair(resourceName, "tunnel2_log_options.0.cloudwatch_log_options.0.bgp_log_group_arn", "aws_cloudwatch_log_group.test", names.AttrARN),
446+
resource.TestCheckResourceAttr(resourceName, "tunnel2_log_options.0.cloudwatch_log_options.0.bgp_log_output_format", "text"),
447+
),
448+
},
449+
},
450+
})
451+
}
452+
403453
func TestAccSiteVPNConnection_transitGatewayID(t *testing.T) {
404454
ctx := acctest.Context(t)
405455
var vpn awstypes.VpnConnection
@@ -2062,6 +2112,88 @@ resource "aws_vpn_connection" "test" {
20622112
`, rName, rBgpAsn)
20632113
}
20642114

2115+
func testAccVPNConnectionConfig_cloudWatchLogOptionsBGPLog(rName string, rBgpAsn int) string {
2116+
return fmt.Sprintf(`
2117+
resource "aws_vpn_gateway" "test" {
2118+
tags = {
2119+
Name = %[1]q
2120+
}
2121+
}
2122+
2123+
resource "aws_customer_gateway" "test" {
2124+
bgp_asn = %[2]d
2125+
ip_address = "178.0.0.1"
2126+
type = "ipsec.1"
2127+
2128+
tags = {
2129+
Name = %[1]q
2130+
}
2131+
}
2132+
2133+
resource "aws_cloudwatch_log_group" "test" {
2134+
name = %[1]q
2135+
}
2136+
2137+
resource "aws_vpn_connection" "test" {
2138+
vpn_gateway_id = aws_vpn_gateway.test.id
2139+
customer_gateway_id = aws_customer_gateway.test.id
2140+
type = "ipsec.1"
2141+
2142+
tunnel1_log_options {
2143+
cloudwatch_log_options {
2144+
bgp_log_enabled = true
2145+
bgp_log_group_arn = aws_cloudwatch_log_group.test.arn
2146+
bgp_log_output_format = "json"
2147+
}
2148+
}
2149+
}
2150+
`, rName, rBgpAsn)
2151+
}
2152+
2153+
func testAccVPNConnectionConfig_cloudWatchLogOptionsBGPLogUpdated(rName string, rBgpAsn int) string {
2154+
return fmt.Sprintf(`
2155+
resource "aws_vpn_gateway" "test" {
2156+
tags = {
2157+
Name = %[1]q
2158+
}
2159+
}
2160+
2161+
resource "aws_customer_gateway" "test" {
2162+
bgp_asn = %[2]d
2163+
ip_address = "178.0.0.1"
2164+
type = "ipsec.1"
2165+
2166+
tags = {
2167+
Name = %[1]q
2168+
}
2169+
}
2170+
2171+
resource "aws_cloudwatch_log_group" "test" {
2172+
name = %[1]q
2173+
}
2174+
2175+
resource "aws_vpn_connection" "test" {
2176+
vpn_gateway_id = aws_vpn_gateway.test.id
2177+
customer_gateway_id = aws_customer_gateway.test.id
2178+
type = "ipsec.1"
2179+
2180+
tunnel1_log_options {
2181+
cloudwatch_log_options {
2182+
bgp_log_enabled = false
2183+
}
2184+
}
2185+
2186+
tunnel2_log_options {
2187+
cloudwatch_log_options {
2188+
bgp_log_enabled = true
2189+
bgp_log_group_arn = aws_cloudwatch_log_group.test.arn
2190+
bgp_log_output_format = "text"
2191+
}
2192+
}
2193+
}
2194+
`, rName, rBgpAsn)
2195+
}
2196+
20652197
func testAccVPNConnectionConfig_customerGatewayID(rName string, rBgpAsn1, rBgpAsn2 int) string {
20662198
return fmt.Sprintf(`
20672199
resource "aws_vpn_gateway" "test" {

website/docs/r/vpn_connection.html.markdown

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ The `tunnel1_log_options` and `tunnel2_log_options` block supports the following
192192

193193
The `cloudwatch_log_options` blocks supports the following arguments:
194194

195+
* `bgp_log_enabled` - (Optional) Enable or disable BGP logging feature. The default is `false`.
196+
* `bgp_log_group_arn` - (Optional) The Amazon Resource Name (ARN) of the CloudWatch log group to send BGP logs to.
197+
* `bgp_log_output_format` - (Optional) Set BGP log format. Default format is json. Possible values are: `json` and `text`. The default is `json`.
195198
* `log_enabled` - (Optional) Enable or disable VPN tunnel logging feature. The default is `false`.
196199
* `log_group_arn` - (Optional) The Amazon Resource Name (ARN) of the CloudWatch log group to send logs to.
197200
* `log_output_format` - (Optional) Set log format. Default format is json. Possible values are: `json` and `text`. The default is `json`.

0 commit comments

Comments
 (0)