github.com/anfernee/terraform@v0.6.16-0.20160430000239-06e5085a92f2/builtin/providers/aws/resource_aws_nat_gateway.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "time" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/awserr" 11 "github.com/aws/aws-sdk-go/service/ec2" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/helper/schema" 14 ) 15 16 func resourceAwsNatGateway() *schema.Resource { 17 return &schema.Resource{ 18 Create: resourceAwsNatGatewayCreate, 19 Read: resourceAwsNatGatewayRead, 20 Delete: resourceAwsNatGatewayDelete, 21 22 Schema: map[string]*schema.Schema{ 23 "allocation_id": &schema.Schema{ 24 Type: schema.TypeString, 25 Required: true, 26 ForceNew: true, 27 }, 28 29 "subnet_id": &schema.Schema{ 30 Type: schema.TypeString, 31 Required: true, 32 ForceNew: true, 33 }, 34 35 "network_interface_id": &schema.Schema{ 36 Type: schema.TypeString, 37 Optional: true, 38 Computed: true, 39 }, 40 41 "private_ip": &schema.Schema{ 42 Type: schema.TypeString, 43 Optional: true, 44 Computed: true, 45 }, 46 47 "public_ip": &schema.Schema{ 48 Type: schema.TypeString, 49 Optional: true, 50 Computed: true, 51 }, 52 }, 53 } 54 } 55 56 func resourceAwsNatGatewayCreate(d *schema.ResourceData, meta interface{}) error { 57 conn := meta.(*AWSClient).ec2conn 58 59 // Create the NAT Gateway 60 createOpts := &ec2.CreateNatGatewayInput{ 61 AllocationId: aws.String(d.Get("allocation_id").(string)), 62 SubnetId: aws.String(d.Get("subnet_id").(string)), 63 } 64 65 log.Printf("[DEBUG] Create NAT Gateway: %s", *createOpts) 66 natResp, err := conn.CreateNatGateway(createOpts) 67 if err != nil { 68 return fmt.Errorf("Error creating NAT Gateway: %s", err) 69 } 70 71 // Get the ID and store it 72 ng := natResp.NatGateway 73 d.SetId(*ng.NatGatewayId) 74 log.Printf("[INFO] NAT Gateway ID: %s", d.Id()) 75 76 // Wait for the NAT Gateway to become available 77 log.Printf("[DEBUG] Waiting for NAT Gateway (%s) to become available", d.Id()) 78 stateConf := &resource.StateChangeConf{ 79 Pending: []string{"pending"}, 80 Target: []string{"available"}, 81 Refresh: NGStateRefreshFunc(conn, d.Id()), 82 Timeout: 10 * time.Minute, 83 } 84 85 if _, err := stateConf.WaitForState(); err != nil { 86 return fmt.Errorf("Error waiting for NAT Gateway (%s) to become available: %s", d.Id(), err) 87 } 88 89 // Update our attributes and return 90 return resourceAwsNatGatewayRead(d, meta) 91 } 92 93 func resourceAwsNatGatewayRead(d *schema.ResourceData, meta interface{}) error { 94 conn := meta.(*AWSClient).ec2conn 95 96 // Refresh the NAT Gateway state 97 ngRaw, state, err := NGStateRefreshFunc(conn, d.Id())() 98 if err != nil { 99 return err 100 } 101 if ngRaw == nil || strings.ToLower(state) == "deleted" { 102 log.Printf("[INFO] Removing %s from Terraform state as it is not found or in the deleted state.", d.Id()) 103 d.SetId("") 104 return nil 105 } 106 107 // Set NAT Gateway attributes 108 ng := ngRaw.(*ec2.NatGateway) 109 d.Set("subnet_id", ng.SubnetId) 110 111 // Address 112 address := ng.NatGatewayAddresses[0] 113 d.Set("allocation_id", address.AllocationId) 114 d.Set("network_interface_id", address.NetworkInterfaceId) 115 d.Set("private_ip", address.PrivateIp) 116 d.Set("public_ip", address.PublicIp) 117 118 return nil 119 } 120 121 func resourceAwsNatGatewayDelete(d *schema.ResourceData, meta interface{}) error { 122 conn := meta.(*AWSClient).ec2conn 123 deleteOpts := &ec2.DeleteNatGatewayInput{ 124 NatGatewayId: aws.String(d.Id()), 125 } 126 log.Printf("[INFO] Deleting NAT Gateway: %s", d.Id()) 127 128 _, err := conn.DeleteNatGateway(deleteOpts) 129 if err != nil { 130 ec2err, ok := err.(awserr.Error) 131 if !ok { 132 return err 133 } 134 135 if ec2err.Code() == "NatGatewayNotFound" { 136 return nil 137 } 138 139 return err 140 } 141 142 stateConf := &resource.StateChangeConf{ 143 Pending: []string{"deleting"}, 144 Target: []string{"deleted"}, 145 Refresh: NGStateRefreshFunc(conn, d.Id()), 146 Timeout: 30 * time.Minute, 147 Delay: 10 * time.Second, 148 MinTimeout: 10 * time.Second, 149 } 150 151 _, stateErr := stateConf.WaitForState() 152 if stateErr != nil { 153 return fmt.Errorf("Error waiting for NAT Gateway (%s) to delete: %s", d.Id(), err) 154 } 155 156 return nil 157 } 158 159 // NGStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 160 // a NAT Gateway. 161 func NGStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { 162 return func() (interface{}, string, error) { 163 opts := &ec2.DescribeNatGatewaysInput{ 164 NatGatewayIds: []*string{aws.String(id)}, 165 } 166 resp, err := conn.DescribeNatGateways(opts) 167 if err != nil { 168 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "NatGatewayNotFound" { 169 resp = nil 170 } else { 171 log.Printf("Error on NGStateRefresh: %s", err) 172 return nil, "", err 173 } 174 } 175 176 if resp == nil { 177 // Sometimes AWS just has consistency issues and doesn't see 178 // our instance yet. Return an empty state. 179 return nil, "", nil 180 } 181 182 ng := resp.NatGateways[0] 183 return ng, *ng.State, nil 184 } 185 }