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