github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/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 address := ng.NatGatewayAddresses[0] 110 d.Set("network_interface_id", address.NetworkInterfaceId) 111 d.Set("private_ip", address.PrivateIp) 112 d.Set("public_ip", address.PublicIp) 113 114 return nil 115 } 116 117 func resourceAwsNatGatewayDelete(d *schema.ResourceData, meta interface{}) error { 118 conn := meta.(*AWSClient).ec2conn 119 deleteOpts := &ec2.DeleteNatGatewayInput{ 120 NatGatewayId: aws.String(d.Id()), 121 } 122 log.Printf("[INFO] Deleting NAT Gateway: %s", d.Id()) 123 124 _, err := conn.DeleteNatGateway(deleteOpts) 125 if err != nil { 126 ec2err, ok := err.(awserr.Error) 127 if !ok { 128 return err 129 } 130 131 if ec2err.Code() == "NatGatewayNotFound" { 132 return nil 133 } 134 135 return err 136 } 137 138 stateConf := &resource.StateChangeConf{ 139 Pending: []string{"deleting"}, 140 Target: []string{"deleted"}, 141 Refresh: NGStateRefreshFunc(conn, d.Id()), 142 Timeout: 30 * time.Minute, 143 Delay: 10 * time.Second, 144 MinTimeout: 10 * time.Second, 145 } 146 147 _, stateErr := stateConf.WaitForState() 148 if stateErr != nil { 149 return fmt.Errorf("Error waiting for NAT Gateway (%s) to delete: %s", d.Id(), err) 150 } 151 152 return nil 153 } 154 155 // NGStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 156 // a NAT Gateway. 157 func NGStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { 158 return func() (interface{}, string, error) { 159 opts := &ec2.DescribeNatGatewaysInput{ 160 NatGatewayIds: []*string{aws.String(id)}, 161 } 162 resp, err := conn.DescribeNatGateways(opts) 163 if err != nil { 164 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "NatGatewayNotFound" { 165 resp = nil 166 } else { 167 log.Printf("Error on NGStateRefresh: %s", err) 168 return nil, "", err 169 } 170 } 171 172 if resp == nil { 173 // Sometimes AWS just has consistency issues and doesn't see 174 // our instance yet. Return an empty state. 175 return nil, "", nil 176 } 177 178 ng := resp.NatGateways[0] 179 return ng, *ng.State, nil 180 } 181 }