Skip to content

Commit

Permalink
Merge branch 'f-route53-vpc-association-authorization' of ssh://githu…
Browse files Browse the repository at this point in the history
…b.com/gazoakley/terraform-provider-aws into gazoakley-f-route53-vpc-association-authorization
  • Loading branch information
bflad committed Aug 6, 2020
2 parents 11fd983 + 65c823f commit 22aee4f
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 30 deletions.
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{
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("")
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
}
}

// 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

0 comments on commit 22aee4f

Please sign in to comment.