Skip to content

Commit 220676a

Browse files
authored
Merge pull request #22911 from hashicorp/b-aws_ec2_client_vpn_network_association-security-group-mixup
r/aws_ec2_client_vpn_network_association: Deprecate `security_groups`; r/aws_ec2_client_vpn_endpoint: Add `security_group_ids` and `vpc_id`
2 parents 8500b6b + 5685620 commit 220676a

20 files changed

+556
-291
lines changed

.changelog/22911.txt

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
```release-note:note
2+
resource/aws_ec2_client_vpn_network_association: The `security_groups` argument has been deprecated. Use the `security_group_ids` argument of the `aws_ec2_client_vpn_endpoint` resource instead
3+
```
4+
5+
```release-note:enhancement
6+
resource/aws_ec2_client_vpn_endpoint: Add `security_group_ids` and `vpc_id` arguments
7+
```
8+
9+
```release-note:enhancement
10+
data-source/aws_ec2_client_vpn_endpoint: Add `security_group_ids` and `vpc_id` attributes
11+
```
12+
13+
```release-note:note
14+
resource/aws_ec2_client_vpn_route: Add [custom `timeouts`](https://www.terraform.io/docs/language/resources/syntax.html#operation-timeouts) block
15+
```

internal/conns/conns.go

+14-11
Original file line numberDiff line numberDiff line change
@@ -1718,26 +1718,29 @@ func (c *Config) Client() (interface{}, error) {
17181718
})
17191719

17201720
client.EC2Conn.Handlers.Retry.PushBack(func(r *request.Request) {
1721-
if r.Operation.Name == "CreateClientVpnEndpoint" {
1722-
if tfawserr.ErrMessageContains(r.Error, "OperationNotPermitted", "Endpoint cannot be created while another endpoint is being created") {
1721+
switch err := r.Error; r.Operation.Name {
1722+
case "AttachVpnGateway", "DetachVpnGateway":
1723+
if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "This call cannot be completed because there are pending VPNs or Virtual Interfaces") {
17231724
r.Retryable = aws.Bool(true)
17241725
}
1725-
}
17261726

1727-
if r.Operation.Name == "CreateVpnConnection" {
1728-
if tfawserr.ErrMessageContains(r.Error, "VpnConnectionLimitExceeded", "maximum number of mutating objects has been reached") {
1727+
case "CreateClientVpnEndpoint":
1728+
if tfawserr.ErrMessageContains(err, "OperationNotPermitted", "Endpoint cannot be created while another endpoint is being created") {
17291729
r.Retryable = aws.Bool(true)
17301730
}
1731-
}
17321731

1733-
if r.Operation.Name == "CreateVpnGateway" {
1734-
if tfawserr.ErrMessageContains(r.Error, "VpnGatewayLimitExceeded", "maximum number of mutating objects has been reached") {
1732+
case "CreateClientVpnRoute", "DeleteClientVpnRoute":
1733+
if tfawserr.ErrMessageContains(err, "ConcurrentMutationLimitExceeded", "Cannot initiate another change for this endpoint at this time") {
1734+
r.Retryable = aws.Bool(true)
1735+
}
1736+
1737+
case "CreateVpnConnection":
1738+
if tfawserr.ErrMessageContains(err, "VpnConnectionLimitExceeded", "maximum number of mutating objects has been reached") {
17351739
r.Retryable = aws.Bool(true)
17361740
}
1737-
}
17381741

1739-
if r.Operation.Name == "AttachVpnGateway" || r.Operation.Name == "DetachVpnGateway" {
1740-
if tfawserr.ErrMessageContains(r.Error, "InvalidParameterValue", "This call cannot be completed because there are pending VPNs or Virtual Interfaces") {
1742+
case "CreateVpnGateway":
1743+
if tfawserr.ErrMessageContains(err, "VpnGatewayLimitExceeded", "maximum number of mutating objects has been reached") {
17411744
r.Retryable = aws.Bool(true)
17421745
}
17431746
}

internal/service/ec2/client_vpn_authorization_rule.go

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/aws/aws-sdk-go/service/ec2"
1010
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
1111
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1213
"github.com/hashicorp/terraform-provider-aws/internal/conns"
1314
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
1415
"github.com/hashicorp/terraform-provider-aws/internal/verify"
@@ -33,6 +34,7 @@ func ResourceClientVPNAuthorizationRule() *schema.Resource {
3334
Type: schema.TypeString,
3435
Optional: true,
3536
ForceNew: true,
37+
ValidateFunc: validation.StringDoesNotContainAny(","),
3638
ExactlyOneOf: []string{"access_group_id", "authorize_all_groups"},
3739
},
3840
"authorize_all_groups": {

internal/service/ec2/client_vpn_endpoint.go

+33
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ func ResourceClientVPNEndpoint() *schema.Resource {
156156
Optional: true,
157157
Elem: &schema.Schema{Type: schema.TypeString},
158158
},
159+
"security_group_ids": {
160+
Type: schema.TypeSet,
161+
MinItems: 1,
162+
MaxItems: 5,
163+
Optional: true,
164+
Computed: true,
165+
Elem: &schema.Schema{Type: schema.TypeString},
166+
},
159167
"self_service_portal": {
160168
Type: schema.TypeString,
161169
Optional: true,
@@ -192,6 +200,11 @@ func ResourceClientVPNEndpoint() *schema.Resource {
192200
Default: ec2.TransportProtocolUdp,
193201
ValidateFunc: validation.StringInSlice(ec2.TransportProtocol_Values(), false),
194202
},
203+
"vpc_id": {
204+
Type: schema.TypeString,
205+
Optional: true,
206+
Computed: true,
207+
},
195208
"vpn_port": {
196209
Type: schema.TypeInt,
197210
Optional: true,
@@ -243,6 +256,10 @@ func resourceClientVPNEndpointCreate(d *schema.ResourceData, meta interface{}) e
243256
input.DnsServers = flex.ExpandStringList(v.([]interface{}))
244257
}
245258

259+
if v, ok := d.GetOk("security_group_ids"); ok {
260+
input.SecurityGroupIds = flex.ExpandStringSet(v.(*schema.Set))
261+
}
262+
246263
if v, ok := d.GetOk("self_service_portal"); ok {
247264
input.SelfServicePortal = aws.String(v.(string))
248265
}
@@ -251,6 +268,10 @@ func resourceClientVPNEndpointCreate(d *schema.ResourceData, meta interface{}) e
251268
input.SessionTimeoutHours = aws.Int64(int64(v.(int)))
252269
}
253270

271+
if v, ok := d.GetOk("vpc_id"); ok {
272+
input.VpcId = aws.String(v.(string))
273+
}
274+
254275
log.Printf("[DEBUG] Creating EC2 Client VPN Endpoint: %s", input)
255276
output, err := conn.CreateClientVpnEndpoint(input)
256277

@@ -316,6 +337,7 @@ func resourceClientVPNEndpointRead(d *schema.ResourceData, meta interface{}) err
316337
d.Set("description", ep.Description)
317338
d.Set("dns_name", ep.DnsName)
318339
d.Set("dns_servers", aws.StringValueSlice(ep.DnsServers))
340+
d.Set("security_group_ids", aws.StringValueSlice(ep.SecurityGroupIds))
319341
if aws.StringValue(ep.SelfServicePortalUrl) != "" {
320342
d.Set("self_service_portal", ec2.SelfServicePortalEnabled)
321343
} else {
@@ -326,6 +348,7 @@ func resourceClientVPNEndpointRead(d *schema.ResourceData, meta interface{}) err
326348
d.Set("split_tunnel", ep.SplitTunnel)
327349
d.Set("status", ep.Status.Code)
328350
d.Set("transport_protocol", ep.TransportProtocol)
351+
d.Set("vpc_id", ep.VpcId)
329352
d.Set("vpn_port", ep.VpnPort)
330353

331354
tags := KeyValueTags(ep.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)
@@ -387,6 +410,12 @@ func resourceClientVPNEndpointUpdate(d *schema.ResourceData, meta interface{}) e
387410
}
388411
}
389412

413+
if d.HasChange("security_group_ids") {
414+
input.SecurityGroupIds = flex.ExpandStringSet(d.Get("security_group_ids").(*schema.Set))
415+
// "InvalidParameterValue: Security Groups cannot be modified without specifying Vpc Id"
416+
input.VpcId = aws.String(d.Get("vpc_id").(string))
417+
}
418+
390419
if d.HasChange("self_service_portal") {
391420
input.SelfServicePortal = aws.String(d.Get("self_service_portal").(string))
392421
}
@@ -407,6 +436,10 @@ func resourceClientVPNEndpointUpdate(d *schema.ResourceData, meta interface{}) e
407436
input.VpnPort = aws.Int64(int64(d.Get("vpn_port").(int)))
408437
}
409438

439+
if d.HasChange("vpc_id") {
440+
input.VpcId = aws.String(d.Get("vpc_id").(string))
441+
}
442+
410443
if _, err := conn.ModifyClientVpnEndpoint(input); err != nil {
411444
return fmt.Errorf("error modifying EC2 Client VPN Endpoint (%s): %w", d.Id(), err)
412445
}

internal/service/ec2/client_vpn_endpoint_data_source.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,16 @@ func DataSourceClientVPNEndpoint() *schema.Resource {
119119
Computed: true,
120120
},
121121
"dns_servers": {
122-
Type: schema.TypeSet,
122+
Type: schema.TypeList,
123123
Computed: true,
124124
Elem: &schema.Schema{Type: schema.TypeString},
125125
},
126126
"filter": DataSourceFiltersSchema(),
127+
"security_group_ids": {
128+
Type: schema.TypeList,
129+
Computed: true,
130+
Elem: &schema.Schema{Type: schema.TypeString},
131+
},
127132
"self_service_portal": {
128133
Type: schema.TypeString,
129134
Computed: true,
@@ -145,6 +150,10 @@ func DataSourceClientVPNEndpoint() *schema.Resource {
145150
Type: schema.TypeString,
146151
Computed: true,
147152
},
153+
"vpc_id": {
154+
Type: schema.TypeString,
155+
Computed: true,
156+
},
148157
"vpn_port": {
149158
Type: schema.TypeInt,
150159
Computed: true,
@@ -219,6 +228,7 @@ func dataSourceClientVPNEndpointRead(d *schema.ResourceData, meta interface{}) e
219228
d.Set("description", ep.Description)
220229
d.Set("dns_name", ep.DnsName)
221230
d.Set("dns_servers", aws.StringValueSlice(ep.DnsServers))
231+
d.Set("security_group_ids", aws.StringValueSlice(ep.SecurityGroupIds))
222232
if aws.StringValue(ep.SelfServicePortalUrl) != "" {
223233
d.Set("self_service_portal", ec2.SelfServicePortalEnabled)
224234
} else {
@@ -228,6 +238,7 @@ func dataSourceClientVPNEndpointRead(d *schema.ResourceData, meta interface{}) e
228238
d.Set("session_timeout_hours", ep.SessionTimeoutHours)
229239
d.Set("split_tunnel", ep.SplitTunnel)
230240
d.Set("transport_protocol", ep.TransportProtocol)
241+
d.Set("vpc_id", ep.VpcId)
231242
d.Set("vpn_port", ep.VpnPort)
232243

233244
if err := d.Set("tags", KeyValueTags(ep.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {

internal/service/ec2/client_vpn_endpoint_data_source_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ func testAccClientVPNEndpointDataSource_basic(t *testing.T) {
3535
resource.TestCheckResourceAttrPair(datasource1Name, "description", resourceName, "description"),
3636
resource.TestCheckResourceAttrPair(datasource1Name, "dns_name", resourceName, "dns_name"),
3737
resource.TestCheckResourceAttrPair(datasource1Name, "dns_servers.#", resourceName, "dns_servers.#"),
38+
resource.TestCheckResourceAttrPair(datasource1Name, "security_group_ids.#", resourceName, "security_group_ids.#"),
3839
resource.TestCheckResourceAttrPair(datasource1Name, "self_service_portal", resourceName, "self_service_portal"),
3940
resource.TestCheckResourceAttrPair(datasource1Name, "server_certificate_arn", resourceName, "server_certificate_arn"),
4041
resource.TestCheckResourceAttrPair(datasource1Name, "session_timeout_hours", resourceName, "session_timeout_hours"),
4142
resource.TestCheckResourceAttrPair(datasource1Name, "split_tunnel", resourceName, "split_tunnel"),
4243
resource.TestCheckResourceAttrPair(datasource1Name, "tags.%", resourceName, "tags.%"),
4344
resource.TestCheckResourceAttrPair(datasource1Name, "transport_protocol", resourceName, "transport_protocol"),
45+
resource.TestCheckResourceAttrPair(datasource1Name, "vpc_id", resourceName, "vpc_id"),
4446
resource.TestCheckResourceAttrPair(datasource1Name, "vpn_port", resourceName, "vpn_port"),
4547

4648
resource.TestCheckResourceAttrPair(datasource2Name, "arn", resourceName, "arn"),
@@ -53,12 +55,14 @@ func testAccClientVPNEndpointDataSource_basic(t *testing.T) {
5355
resource.TestCheckResourceAttrPair(datasource2Name, "description", resourceName, "description"),
5456
resource.TestCheckResourceAttrPair(datasource2Name, "dns_name", resourceName, "dns_name"),
5557
resource.TestCheckResourceAttrPair(datasource2Name, "dns_servers.#", resourceName, "dns_servers.#"),
58+
resource.TestCheckResourceAttrPair(datasource2Name, "security_group_ids.#", resourceName, "security_group_ids.#"),
5659
resource.TestCheckResourceAttrPair(datasource2Name, "self_service_portal", resourceName, "self_service_portal"),
5760
resource.TestCheckResourceAttrPair(datasource2Name, "server_certificate_arn", resourceName, "server_certificate_arn"),
5861
resource.TestCheckResourceAttrPair(datasource2Name, "session_timeout_hours", resourceName, "session_timeout_hours"),
5962
resource.TestCheckResourceAttrPair(datasource2Name, "split_tunnel", resourceName, "split_tunnel"),
6063
resource.TestCheckResourceAttrPair(datasource2Name, "tags.%", resourceName, "tags.%"),
6164
resource.TestCheckResourceAttrPair(datasource2Name, "transport_protocol", resourceName, "transport_protocol"),
65+
resource.TestCheckResourceAttrPair(datasource2Name, "vpc_id", resourceName, "vpc_id"),
6266
resource.TestCheckResourceAttrPair(datasource2Name, "vpn_port", resourceName, "vpn_port"),
6367

6468
resource.TestCheckResourceAttrPair(datasource3Name, "arn", resourceName, "arn"),
@@ -71,12 +75,14 @@ func testAccClientVPNEndpointDataSource_basic(t *testing.T) {
7175
resource.TestCheckResourceAttrPair(datasource3Name, "description", resourceName, "description"),
7276
resource.TestCheckResourceAttrPair(datasource3Name, "dns_name", resourceName, "dns_name"),
7377
resource.TestCheckResourceAttrPair(datasource3Name, "dns_servers.#", resourceName, "dns_servers.#"),
78+
resource.TestCheckResourceAttrPair(datasource3Name, "security_group_ids.#", resourceName, "security_group_ids.#"),
7479
resource.TestCheckResourceAttrPair(datasource3Name, "self_service_portal", resourceName, "self_service_portal"),
7580
resource.TestCheckResourceAttrPair(datasource3Name, "server_certificate_arn", resourceName, "server_certificate_arn"),
7681
resource.TestCheckResourceAttrPair(datasource3Name, "session_timeout_hours", resourceName, "session_timeout_hours"),
7782
resource.TestCheckResourceAttrPair(datasource3Name, "split_tunnel", resourceName, "split_tunnel"),
7883
resource.TestCheckResourceAttrPair(datasource3Name, "tags.%", resourceName, "tags.%"),
7984
resource.TestCheckResourceAttrPair(datasource3Name, "transport_protocol", resourceName, "transport_protocol"),
85+
resource.TestCheckResourceAttrPair(datasource3Name, "vpc_id", resourceName, "vpc_id"),
8086
resource.TestCheckResourceAttrPair(datasource3Name, "vpn_port", resourceName, "vpn_port"),
8187
),
8288
},

0 commit comments

Comments
 (0)