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 #2005

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ func Provider() terraform.ResourceProvider {
"aws_redshift_subnet_group": resourceAwsRedshiftSubnetGroup(),
"aws_route53_delegation_set": resourceAwsRoute53DelegationSet(),
"aws_route53_record": resourceAwsRoute53Record(),
"aws_route53_vpc_association_authorization": resourceAwsRoute53VPCAssociationAuthorization(),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned elsewhere, this should probably be aws_route53_zone_association_authorization. Even better, would probably be aws_route53_zone_association_accepter (depending on what it actually do - I'm not a fan of Go! :).

This because we already have:

aws_vpc_peering_connection
aws_vpc_peering_connection_accepter

So having the r53 resources being named

aws_route53_zone_association
aws_route53_zone_association_accepter

makes sense. Pretty if nothing else :D

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aws_route53_vpc_association_authorization would match the name of the API call that creates it, though:

https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateVPCAssociationAuthorization.html

"aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(),
"aws_route53_zone": resourceAwsRoute53Zone(),
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
Expand Down
127 changes: 127 additions & 0 deletions aws/resource_aws_route53_vpc_association_authorization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package aws

import (
"fmt"
"log"
"strings"

"github.com/hashicorp/terraform/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,

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

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

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

func resourceAwsRoute53VPCAssociationAuthorizationCreate(d *schema.ResourceData, meta interface{}) error {
r53 := 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 w := d.Get("vpc_region"); w != "" {
req.VPC.VPCRegion = aws.String(w.(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)
var err error
_, err = r53.CreateVPCAssociationAuthorization(req)
if err != nil {
return err
}

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

return resourceAwsRoute53VPCAssociationAuthorizationRead(d, meta)
}

func resourceAwsRoute53VPCAssociationAuthorizationRead(d *schema.ResourceData, meta interface{}) error {
r53 := meta.(*AWSClient).r53conn
zone_id, vpc_id := resourceAwsRoute53VPCAssociationAuthorizationParseId(d.Id())
req := route53.ListVPCAssociationAuthorizationsInput{HostedZoneId: aws.String(zone_id)}
for {
res, err := r53.ListVPCAssociationAuthorizations(&req)
if err != nil {
return err
}

for _, vpc := range res.VPCs {
if vpc_id == *vpc.VPCId {
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
d.SetId("")
return nil
}

func resourceAwsRoute53VPCAssociationAuthorizationDelete(d *schema.ResourceData, meta interface{}) error {
r53 := meta.(*AWSClient).r53conn
zone_id, vpc_id := resourceAwsRoute53VPCAssociationAuthorizationParseId(d.Id())
log.Printf("[DEBUG] Deleting Route53 Assocatiation Authorization for (%s) from vpc %s)",
zone_id, vpc_id)

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

_, err := r53.DeleteVPCAssociationAuthorization(&req)
if err != nil {
return err
}

return nil
}

func resourceAwsRoute53VPCAssociationAuthorizationParseId(id string) (zone_id, vpc_id string) {
parts := strings.SplitN(id, ":", 2)
zone_id = parts[0]
vpc_id = parts[1]
return
}
233 changes: 233 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,233 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"

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

func TestAccAWSRoute53VpcAssociationAuthorization_basic(t *testing.T) {
var zone route53.HostedZone

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckRoute53VPCAssociationAuthorizationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccRoute53VPCAssociationAuthorizationConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckRoute53VPCAssociationAuthorizationExists("aws_route53_vpc_association_authorization.peer", &zone),
),
},
},
})
}

func TestAccAWSRoute53VPCAssociationAuthorization_region(t *testing.T) {
var zone route53.HostedZone

// record the initialized providers so that we can use them to
// check for the instances in each region
var providers []*schema.Provider
providerFactories := map[string]terraform.ResourceProviderFactory{
"aws": func() (terraform.ResourceProvider, error) {
p := Provider()
providers = append(providers, p.(*schema.Provider))
return p, nil
},
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
CheckDestroy: testAccCheckRoute53VPCAssociationAuthorizationDestroyWithProviders(&providers),
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccRoute53ZoneAssociationRegionConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckRoute53VPCAssociationAuthorizationExistsWithProviders("aws_route53_vpc_association_authorization.peer", &zone, &providers),
),
},
},
})
}

func testAccCheckRoute53VPCAssociationAuthorizationDestroy(s *terraform.State) error {
return testAccCheckRoute53VPCAssociationAuthorizationDestroyWithProvider(s, testAccProvider)
}

func testAccCheckRoute53VPCAssociationAuthorizationDestroyWithProviders(providers *[]*schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
for _, provider := range *providers {
if provider.Meta() == nil {
continue
}
if err := testAccCheckRoute53VPCAssociationAuthorizationDestroyWithProvider(s, provider); err != nil {
return err
}
}
return nil
}
}

func testAccCheckRoute53VPCAssociationAuthorizationDestroyWithProvider(s *terraform.State, provider *schema.Provider) error {
conn := provider.Meta().(*AWSClient).r53conn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_route53_vpc_association_authorization" {
continue
}

zone_id, vpc_id := resourceAwsRoute53ZoneAssociationParseId(rs.Primary.ID)

req := route53.ListVPCAssociationAuthorizationsInput{HostedZoneId: aws.String(zone_id)}
res, err := conn.ListVPCAssociationAuthorizations(&req)
if err != nil {
return err
}

exists := false
for _, vpc := range res.VPCs {
if vpc_id == *vpc.VPCId {
exists = true
}
}

if exists {
return fmt.Errorf("VPC association authorization for zone %v with %v still exists", zone_id, vpc_id)
}
}
return nil
}

func testAccCheckRoute53VPCAssociationAuthorizationExists(n string, zone *route53.HostedZone) resource.TestCheckFunc {
return func(s *terraform.State) error {
return testAccCheckRoute53VPCAssociationAuthorizationExistsWithProvider(s, n, zone, testAccProvider)
}
}

func testAccCheckRoute53VPCAssociationAuthorizationExistsWithProviders(n string, zone *route53.HostedZone, providers *[]*schema.Provider) resource.TestCheckFunc {
return func(s *terraform.State) error {
for _, provider := range *providers {
if provider.Meta() == nil {
continue
}
if err := testAccCheckRoute53VPCAssociationAuthorizationExistsWithProvider(s, n, zone, provider); err != nil {
return err
}
}
return nil
}
}

func testAccCheckRoute53VPCAssociationAuthorizationExistsWithProvider(s *terraform.State, n string, zone *route53.HostedZone, provider *schema.Provider) 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 := resourceAwsRoute53ZoneAssociationParseId(rs.Primary.ID)
conn := provider.Meta().(*AWSClient).r53conn

req := route53.ListVPCAssociationAuthorizationsInput{HostedZoneId: aws.String(zone_id)}
res, err := conn.ListVPCAssociationAuthorizations(&req)
if err != nil {
return err
}

exists := false
for _, vpc := range res.VPCs {
if vpc_id == *vpc.VPCId {
exists = true
}
}

if !exists {
return fmt.Errorf("VPC association authorization not found")
}

return nil
}

const testAccRoute53VPCAssociationAuthorizationConfig = `
provider "aws" {
region = "us-west-2"
// Requester's credentials.
}
provider "aws" {
alias = "peer"
region = "us-west-2"
}
resource "aws_vpc" "foo" {
cidr_block = "10.6.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_vpc" "peer" {
provider = "aws.peer"
cidr_block = "10.7.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_route53_zone" "foo" {
name = "foo.com"
vpc_id = "${aws_vpc.foo.id}"
}
resource "aws_route53_vpc_association_authorization" "peer" {
zone_id = "${aws_route53_zone.foo.id}"
vpc_id = "${aws_vpc.peer.id}"
}

# Not supported currently (https://github.com/terraform-providers/terraform-provider-aws/issues/384)
#resource "aws_route53_zone_association" "foobar" {
# zone_id = "${aws_route53_zone.foo.id}"
# vpc_id = "${aws_vpc.peer.id}"
#}
`

const testAccRoute53VPCAssociationAuthorizationRegionConfig = `
provider "aws" {
region = "us-west-1"
// Requester's credentials.
}
provider "aws" {
alias = "peer"
region = "us-east-2"
}
resource "aws_vpc" "foo" {
cidr_block = "10.6.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_vpc" "peer" {
provider = "aws.peer"
cidr_block = "10.7.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_route53_zone" "foo" {
name = "foo.com"
vpc_id = "${aws_vpc.foo.id}"
}
resource "aws_route53_vpc_association_authorization" "peer" {
zone_id = "${aws_route53_zone.foo.id}"
vpc_id = "${aws_vpc.peer.id}"
}

# Not supported currently (https://github.com/terraform-providers/terraform-provider-aws/issues/384)
#resource "aws_route53_zone_association" "foobar" {
# zone_id = "${aws_route53_zone.foo.id}"
# vpc_id = "${aws_vpc.peer.id}"
# region = "us-east-2"
#}
`