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  }