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

New Resource: aws_route53_vpc_association_authorization #14215

Merged
Merged
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ func Provider() terraform.ResourceProvider {
"aws_route53_query_log": resourceAwsRoute53QueryLog(),
"aws_route53_record": resourceAwsRoute53Record(),
"aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(),
"aws_route53_vpc_association_authorization": resourceAwsRoute53VPCAssociationAuthorization(),
"aws_route53_zone": resourceAwsRoute53Zone(),
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
"aws_route53_resolver_endpoint": resourceAwsRoute53ResolverEndpoint(),
Expand Down
155 changes: 155 additions & 0 deletions aws/resource_aws_route53_vpc_association_authorization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package aws

import (
"fmt"
"log"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53"
)

func resourceAwsRoute53VPCAssociationAuthorization() *schema.Resource {
return &schema.Resource{
gazoakley marked this conversation as resolved.
Show resolved Hide resolved
Create: resourceAwsRoute53VPCAssociationAuthorizationCreate,
Read: resourceAwsRoute53VPCAssociationAuthorizationRead,
Delete: resourceAwsRoute53VPCAssociationAuthorizationDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"zone_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"vpc_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"vpc_region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
}

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

req := &route53.CreateVPCAssociationAuthorizationInput{
HostedZoneId: aws.String(d.Get("zone_id").(string)),
VPC: &route53.VPC{
VPCId: aws.String(d.Get("vpc_id").(string)),
VPCRegion: aws.String(meta.(*AWSClient).region),
},
}

if v, ok := d.GetOk("vpc_region"); ok {
req.VPC.VPCRegion = aws.String(v.(string))
}

log.Printf("[DEBUG] Creating Route53 VPC Association Authorization for hosted zone %s with VPC %s and region %s", *req.HostedZoneId, *req.VPC.VPCId, *req.VPC.VPCRegion)
_, err := conn.CreateVPCAssociationAuthorization(req)
if err != nil {
return fmt.Errorf("Error creating Route53 VPC Association Authorization: %s", err)
}

// Store association id
d.SetId(fmt.Sprintf("%s:%s", *req.HostedZoneId, *req.VPC.VPCId))

return resourceAwsRoute53VPCAssociationAuthorizationRead(d, meta)
}

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

zone_id, vpc_id, err := resourceAwsRoute53VPCAssociationAuthorizationParseId(d.Id())
if err != nil {
return err
}

req := route53.ListVPCAssociationAuthorizationsInput{
HostedZoneId: aws.String(zone_id),
}

for {
log.Printf("[DEBUG] Listing Route53 VPC Association Authorizations for hosted zone %s", zone_id)
res, err := conn.ListVPCAssociationAuthorizations(&req)

if isAWSErr(err, route53.ErrCodeNoSuchHostedZone, "") {
log.Printf("[WARN] Route53 VPC Association Authorization (%s) not found, removing from state", d.Id())
d.SetId("")
gazoakley marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

if err != nil {
return fmt.Errorf("Error listing Route53 VPC Association Authorizations: %s", err)
}

for _, vpc := range res.VPCs {
if vpc_id == aws.StringValue(vpc.VPCId) {
d.Set("vpc_id", vpc.VPCId)
d.Set("vpc_region", vpc.VPCRegion)
d.Set("zone_id", zone_id)
return nil
gazoakley marked this conversation as resolved.
Show resolved Hide resolved
}
}

// Loop till we find our authorization or we reach the end
if res.NextToken != nil {
req.NextToken = res.NextToken
} else {
break
}
}

// no association found
log.Printf("[WARN] Route53 VPC Association Authorization (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

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

zone_id, vpc_id, err := resourceAwsRoute53VPCAssociationAuthorizationParseId(d.Id())
if err != nil {
return err
}

req := route53.DeleteVPCAssociationAuthorizationInput{
HostedZoneId: aws.String(zone_id),
VPC: &route53.VPC{
VPCId: aws.String(vpc_id),
VPCRegion: aws.String(d.Get("vpc_region").(string)),
},
}

log.Printf("[DEBUG] Deleting Route53 Assocatiation Authorization for hosted zone %s for VPC %s", zone_id, vpc_id)
_, err = conn.DeleteVPCAssociationAuthorization(&req)
if err != nil {
return fmt.Errorf("Error deleting Route53 VPC Association Authorization: %s", err)
}

return nil
}

func resourceAwsRoute53VPCAssociationAuthorizationParseId(id string) (string, string, error) {
parts := strings.SplitN(id, ":", 2)

if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return "", "", fmt.Errorf("Unexpected format of ID (%q), expected ZONEID:VPCID", id)
}

return parts[0], parts[1], nil
}
141 changes: 141 additions & 0 deletions aws/resource_aws_route53_vpc_association_authorization_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/terraform"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53"
)

func TestAccAWSRoute53VpcAssociationAuthorization_basic(t *testing.T) {
var providers []*schema.Provider
resourceName := "aws_route53_vpc_association_authorization.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccAlternateAccountPreCheck(t)
},
ProviderFactories: testAccProviderFactories(&providers),
CheckDestroy: testAccCheckRoute53VPCAssociationAuthorizationDestroy,
Steps: []resource.TestStep{
{
Config: testAccRoute53VPCAssociationAuthorizationConfig(),
Check: resource.ComposeTestCheckFunc(
testAccCheckRoute53VPCAssociationAuthorizationExists(resourceName),
),
},
{
Config: testAccRoute53VPCAssociationAuthorizationConfig(),
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

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

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_route53_vpc_association_authorization" {
continue
}

zone_id, vpc_id, err := resourceAwsRoute53ZoneAssociationParseId(rs.Primary.ID)
if err != nil {
return err
}

req := route53.ListVPCAssociationAuthorizationsInput{
HostedZoneId: aws.String(zone_id),
}

res, err := conn.ListVPCAssociationAuthorizations(&req)
if isAWSErr(err, route53.ErrCodeNoSuchHostedZone, "") {
return nil
}
if err != nil {
return err
}

for _, vpc := range res.VPCs {
if vpc_id == *vpc.VPCId {
return fmt.Errorf("VPC association authorization for zone %v with %v still exists", zone_id, vpc_id)
}
}
}
return nil
}

func testAccCheckRoute53VPCAssociationAuthorizationExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No VPC association authorization ID is set")
}

zone_id, vpc_id, err := resourceAwsRoute53ZoneAssociationParseId(rs.Primary.ID)
if err != nil {
return err
}

conn := testAccProvider.Meta().(*AWSClient).r53conn

req := route53.ListVPCAssociationAuthorizationsInput{
HostedZoneId: aws.String(zone_id),
}

res, err := conn.ListVPCAssociationAuthorizations(&req)
if err != nil {
return err
}

for _, vpc := range res.VPCs {
if vpc_id == *vpc.VPCId {
return nil
}
}

return fmt.Errorf("VPC association authorization not found")
}
}

func testAccRoute53VPCAssociationAuthorizationConfig() string {
return testAccAlternateAccountProviderConfig() + `
resource "aws_vpc" "test" {
cidr_block = "10.6.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}

resource "aws_route53_zone" "test" {
name = "example.com"
vpc {
vpc_id = aws_vpc.test.id
}
}

resource "aws_vpc" "alternate" {
provider = "awsalternate"
cidr_block = "10.7.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}

resource "aws_route53_vpc_association_authorization" "test" {
zone_id = aws_route53_zone.test.id
vpc_id = aws_vpc.alternate.id
}
`
}
Loading