Skip to content

Commit

Permalink
resource/aws_vpc_endpoint_service: Make private_dns_name configurab…
Browse files Browse the repository at this point in the history
…le and add `private_dns_name_configuration` attribute (#16495)

Output from acceptance testing:

```
--- PASS: TestAccAWSVpcEndpointService_GatewayLoadBalancerArns (211.72s)
--- PASS: TestAccAWSVpcEndpointService_disappears (259.98s)
--- PASS: TestAccAWSVpcEndpointService_private_dns_name (260.23s)
--- PASS: TestAccAWSVpcEndpointService_tags (260.39s)
--- PASS: TestAccAWSVpcEndpointService_basic (315.92s)
--- PASS: TestAccAWSVpcEndpointService_AllowedPrincipals (326.95s)
```
  • Loading branch information
stijndehaes committed Jan 5, 2021
1 parent 2dd0e84 commit f6880bb
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 2 deletions.
69 changes: 68 additions & 1 deletion aws/resource_aws_vpc_endpoint_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ func resourceAwsVpcEndpointService() *schema.Resource {
"private_dns_name": {
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"private_dns_name_configuration": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"state": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"value": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"service_name": {
Type: schema.TypeString,
Expand All @@ -104,6 +129,9 @@ func resourceAwsVpcEndpointServiceCreate(d *schema.ResourceData, meta interface{
AcceptanceRequired: aws.Bool(d.Get("acceptance_required").(bool)),
TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), "vpc-endpoint-service"),
}
if v, ok := d.GetOk("private_dns_name"); ok {
req.PrivateDnsName = aws.String(v.(string))
}

if v, ok := d.GetOk("gateway_load_balancer_arns"); ok {
if v, ok := v.(*schema.Set); ok && v.Len() > 0 {
Expand Down Expand Up @@ -214,17 +242,56 @@ func resourceAwsVpcEndpointServiceRead(d *schema.ResourceData, meta interface{})
return fmt.Errorf("error setting allowed_principals: %s", err)
}

err = d.Set("private_dns_name_configuration", flattenPrivateDnsNameConfiguration(svcCfg.PrivateDnsNameConfiguration))
if err != nil {
return fmt.Errorf("error setting private_dns_name_configuration: %w", err)
}

return nil
}

func flattenPrivateDnsNameConfiguration(privateDnsNameConfiguration *ec2.PrivateDnsNameConfiguration) []interface{} {
if privateDnsNameConfiguration == nil {
return nil
}
tfMap := map[string]interface{}{}

if v := privateDnsNameConfiguration.Name; v != nil {
tfMap["name"] = aws.StringValue(v)
}

if v := privateDnsNameConfiguration.State; v != nil {
tfMap["state"] = aws.StringValue(v)
}

if v := privateDnsNameConfiguration.Type; v != nil {
tfMap["type"] = aws.StringValue(v)
}

if v := privateDnsNameConfiguration.Value; v != nil {
tfMap["value"] = aws.StringValue(v)
}

// The EC2 API can return a XML structure with no elements
if len(tfMap) == 0 {
return nil
}

return []interface{}{tfMap}
}

func resourceAwsVpcEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

if d.HasChanges("acceptance_required", "gateway_load_balancer_arns", "network_load_balancer_arns") {
if d.HasChanges("acceptance_required", "gateway_load_balancer_arns", "network_load_balancer_arns", "private_dns_name") {
modifyCfgReq := &ec2.ModifyVpcEndpointServiceConfigurationInput{
ServiceId: aws.String(d.Id()),
}

if d.HasChange("private_dns_name") {
modifyCfgReq.PrivateDnsName = aws.String(d.Get("private_dns_name").(string))
}

if d.HasChange("acceptance_required") {
modifyCfgReq.AcceptanceRequired = aws.Bool(d.Get("acceptance_required").(bool))
}
Expand Down
54 changes: 54 additions & 0 deletions aws/resource_aws_vpc_endpoint_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func TestAccAWSVpcEndpointService_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "0"),
resource.TestCheckResourceAttr(resourceName, "manages_vpc_endpoints", "false"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "0"),
testAccMatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)),
),
},
Expand Down Expand Up @@ -256,6 +257,44 @@ func TestAccAWSVpcEndpointService_tags(t *testing.T) {
})
}

func TestAccAWSVpcEndpointService_private_dns_name(t *testing.T) {
var svcCfg ec2.ServiceConfiguration
resourceName := "aws_vpc_endpoint_service.test"
rName1 := acctest.RandomWithPrefix("tf-acc-test")
rName2 := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckVpcEndpointServiceDestroy,
Steps: []resource.TestStep{
{
Config: testAccVpcEndpointServiceConfigPrivateDnsName(rName1, rName2, "example.com"),
Check: resource.ComposeTestCheckFunc(
testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg),
resource.TestCheckResourceAttr(resourceName, "private_dns_name", "example.com"),
resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.0.type", "TXT"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccVpcEndpointServiceConfigPrivateDnsName(rName1, rName2, "changed.com"),
Check: resource.ComposeTestCheckFunc(
testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg),
resource.TestCheckResourceAttr(resourceName, "private_dns_name", "changed.com"),
resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.0.type", "TXT"),
),
},
},
})
}

func testAccCheckVpcEndpointServiceDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn

Expand Down Expand Up @@ -525,3 +564,18 @@ resource "aws_vpc_endpoint_service" "test" {
}
`, tagKey1, tagValue1, tagKey2, tagValue2))
}

func testAccVpcEndpointServiceConfigPrivateDnsName(rName1, rName2, dnsName string) string {
return composeConfig(
testAccVpcEndpointServiceConfig_base(rName1, rName2),
fmt.Sprintf(`
resource "aws_vpc_endpoint_service" "test" {
acceptance_required = false
private_dns_name = "%s"
network_load_balancer_arns = [
aws_lb.test1.arn,
]
}
`, dnsName))
}
7 changes: 6 additions & 1 deletion website/docs/r/vpc_endpoint_service.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The following arguments are supported:
* `gateway_load_balancer_arns` - (Optional) Amazon Resource Names (ARNs) of one or more Gateway Load Balancers for the endpoint service.
* `network_load_balancer_arns` - (Optional) Amazon Resource Names (ARNs) of one or more Network Load Balancers for the endpoint service.
* `tags` - (Optional) A map of tags to assign to the resource.
* `private_dns_name` - (Optional) The private DNS name for the service.

## Attributes Reference

Expand All @@ -56,10 +57,14 @@ In addition to all arguments above, the following attributes are exported:
* `arn` - The Amazon Resource Name (ARN) of the VPC endpoint service.
* `base_endpoint_dns_names` - The DNS names for the service.
* `manages_vpc_endpoints` - Whether or not the service manages its VPC endpoints - `true` or `false`.
* `private_dns_name` - The private DNS name for the service.
* `service_name` - The service name.
* `service_type` - The service type, `Gateway` or `Interface`.
* `state` - The state of the VPC endpoint service.
* `private_dns_name_configuration` - List of objects containing information about the endpoint service private DNS name configuration.
* `name` - Name of the record subdomain the service provider needs to create.
* `state` - Verification state of the VPC endpoint service. Consumers of the endpoint service can use the private name only when the state is `verified`.
* `type` - Endpoint service verification type, for example `TXT`.
* `value` - Value the service provider adds to the private DNS name domain record before verification.

## Import

Expand Down

0 comments on commit f6880bb

Please sign in to comment.