From e4fa33688f9d786bc1b4a062dff4326c46d9222e Mon Sep 17 00:00:00 2001 From: yamamototakahiro Date: Sat, 24 Jun 2017 20:41:52 +0900 Subject: [PATCH] add resource was network cal association --- builtin/providers/aws/provider.go | 1 + .../resource_aws_network_acl_association.go | 139 ++++++++++++++++++ ...source_aws_network_acl_association_test.go | 70 +++++++++ 3 files changed, 210 insertions(+) create mode 100644 builtin/providers/aws/resource_aws_network_acl_association.go create mode 100644 builtin/providers/aws/resource_aws_network_acl_association_test.go diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 0a961929767c..ba4a66767d81 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -373,6 +373,7 @@ func Provider() terraform.ResourceProvider { "aws_main_route_table_association": resourceAwsMainRouteTableAssociation(), "aws_nat_gateway": resourceAwsNatGateway(), "aws_network_acl": resourceAwsNetworkAcl(), + "aws_network_acl_association": resourceAwsNetworkAclAssociation(), "aws_default_network_acl": resourceAwsDefaultNetworkAcl(), "aws_network_acl_rule": resourceAwsNetworkAclRule(), "aws_network_interface": resourceAwsNetworkInterface(), diff --git a/builtin/providers/aws/resource_aws_network_acl_association.go b/builtin/providers/aws/resource_aws_network_acl_association.go new file mode 100644 index 000000000000..d551de26a551 --- /dev/null +++ b/builtin/providers/aws/resource_aws_network_acl_association.go @@ -0,0 +1,139 @@ +package aws + +import ( + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsNetworkAclAssociation() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsNetworkAclAssociationCreate, + Read: resourceAwsNetworkAclAssociationRead, + Update: resourceAwsNetworkAclAssociationUpdate, + Delete: resourceAwsNetworkAclAssociationDelete, + + Schema: map[string]*schema.Schema{ + "subnet_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "network_acl_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceAwsNetworkAclAssociationCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + naclId := d.Get("network_acl_id").(string) + subnetId := d.Get("subnet_id").(string) + + log.Printf( + "[INFO] Creating network acl association: %s => %s", + subnetId, + naclId) + + association, err_association := findNetworkAclAssociation(subnetId, conn) + if err_association != nil { + return fmt.Errorf("Failed to create acl %s with nacl %s: %s", d.Id(), naclId, err_association) + } + + associationOpts := ec2.ReplaceNetworkAclAssociationInput{ + AssociationId: association.NetworkAclAssociationId, + NetworkAclId: aws.String(naclId), + } + + var err error + err = resource.Retry(5*time.Minute, func() *resource.RetryError { + _, err = conn.ReplaceNetworkAclAssociation(&associationOpts) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr != nil { + return resource.RetryableError(awsErr) + } + } + return resource.NonRetryableError(err) + } + return nil + }) + if err != nil { + return err + } + + // Set the ID and return + d.SetId(naclId) + log.Printf("[INFO] Association ID: %s", d.Id()) + + return nil +} + +func resourceAwsNetworkAclAssociationRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + // Inspect that the association exists + subnetId := d.Get("subnet_id").(string) + _, err_association := findNetworkAclAssociation(subnetId, conn) + if err_association != nil { + return fmt.Errorf("Failed to read acl %s with subnet %s: %s", d.Id(), subnetId, err_association) + d.SetId("") + } + + return nil +} + +func resourceAwsNetworkAclAssociationUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + + naclId := d.Get("network_acl_id").(string) + subnetId := d.Get("subnet_id").(string) + + log.Printf( + "[INFO] Creating network acl association: %s => %s", + subnetId, + naclId) + + association, err_association := findNetworkAclAssociation(subnetId, conn) + if err_association != nil { + return fmt.Errorf("Failed to update acl %s with subnet %s: %s", d.Id(), naclId, err_association) + } + + req := &ec2.ReplaceNetworkAclAssociationInput{ + AssociationId: association.NetworkAclAssociationId, + NetworkAclId: aws.String(naclId), + } + resp, err := conn.ReplaceNetworkAclAssociation(req) + + if err != nil { + ec2err, ok := err.(awserr.Error) + if ok && ec2err.Code() == "InvalidAssociationID.NotFound" { + // Not found, so just create a new one + return resourceAwsNetworkAclAssociationCreate(d, meta) + } + + return err + } + + // Update the ID + d.SetId(*resp.NewAssociationId) + log.Printf("[INFO] Association ID: %s", d.Id()) + + return nil +} + +func resourceAwsNetworkAclAssociationDelete(d *schema.ResourceData, meta interface{}) error { + + log.Printf("[INFO] Do nothing on network acl associatioƘ destroy phase: %s", d.Id()) + + return nil +} diff --git a/builtin/providers/aws/resource_aws_network_acl_association_test.go b/builtin/providers/aws/resource_aws_network_acl_association_test.go new file mode 100644 index 000000000000..a422563da86f --- /dev/null +++ b/builtin/providers/aws/resource_aws_network_acl_association_test.go @@ -0,0 +1,70 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSNetworkAclAssociation(t *testing.T) { + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_network_acl.bar", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSNetworkAclDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSNetworkAclAssoc, + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAwsRMNetworkAclAssocExists("aws_network_acl_association.test"), + ), + }, + }, + }) +} + +func testCheckAwsRMNetworkAclAssocExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + + _, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + return nil + } +} + +const testAccAWSNetworkAclAssoc = ` +resource "aws_vpc" "testespvpc" { + cidr_block = "10.1.0.0/16" + tags { + Name = "testAccAWSNetworkAclEsp" + } +} + + resource "aws_network_acl" "acl_a" { + vpc_id = "${aws_vpc.testespvpc.id}" + + tags { + Name = "terraform test" + } + } + + resource "aws_subnet" "sunet_a" { + vpc_id = "${aws_vpc.testespvpc.id}" + cidr_block = "10.0.33.0/24" + tags { + Name = "terraform test" + } + } + + resource "aws_network_acl_association" "test" { + network_acl_id = "${aws_network_acl.acl_a.id}" + subnet_id = "${aws_subnet.subnet_a.id}" + } +} +`