github.com/erriapo/terraform@v0.6.12-0.20160203182612-0340ea72354f/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  }