github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_customer_gateway.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     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  
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/helper/schema"
    15  )
    16  
    17  func resourceAwsCustomerGateway() *schema.Resource {
    18  	return &schema.Resource{
    19  		Create: resourceAwsCustomerGatewayCreate,
    20  		Read:   resourceAwsCustomerGatewayRead,
    21  		Update: resourceAwsCustomerGatewayUpdate,
    22  		Delete: resourceAwsCustomerGatewayDelete,
    23  		Importer: &schema.ResourceImporter{
    24  			State: schema.ImportStatePassthrough,
    25  		},
    26  
    27  		Schema: map[string]*schema.Schema{
    28  			"bgp_asn": &schema.Schema{
    29  				Type:     schema.TypeInt,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  
    34  			"ip_address": &schema.Schema{
    35  				Type:     schema.TypeString,
    36  				Required: true,
    37  				ForceNew: true,
    38  			},
    39  
    40  			"type": &schema.Schema{
    41  				Type:     schema.TypeString,
    42  				Required: true,
    43  				ForceNew: true,
    44  			},
    45  
    46  			"tags": tagsSchema(),
    47  		},
    48  	}
    49  }
    50  
    51  func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{}) error {
    52  	conn := meta.(*AWSClient).ec2conn
    53  
    54  	createOpts := &ec2.CreateCustomerGatewayInput{
    55  		BgpAsn:   aws.Int64(int64(d.Get("bgp_asn").(int))),
    56  		PublicIp: aws.String(d.Get("ip_address").(string)),
    57  		Type:     aws.String(d.Get("type").(string)),
    58  	}
    59  
    60  	// Create the Customer Gateway.
    61  	log.Printf("[DEBUG] Creating customer gateway")
    62  	resp, err := conn.CreateCustomerGateway(createOpts)
    63  	if err != nil {
    64  		return fmt.Errorf("Error creating customer gateway: %s", err)
    65  	}
    66  
    67  	// Store the ID
    68  	customerGateway := resp.CustomerGateway
    69  	d.SetId(*customerGateway.CustomerGatewayId)
    70  	log.Printf("[INFO] Customer gateway ID: %s", *customerGateway.CustomerGatewayId)
    71  
    72  	// Wait for the CustomerGateway to be available.
    73  	stateConf := &resource.StateChangeConf{
    74  		Pending:    []string{"pending"},
    75  		Target:     []string{"available"},
    76  		Refresh:    customerGatewayRefreshFunc(conn, *customerGateway.CustomerGatewayId),
    77  		Timeout:    10 * time.Minute,
    78  		Delay:      10 * time.Second,
    79  		MinTimeout: 3 * time.Second,
    80  	}
    81  
    82  	_, stateErr := stateConf.WaitForState()
    83  	if stateErr != nil {
    84  		return fmt.Errorf(
    85  			"Error waiting for customer gateway (%s) to become ready: %s",
    86  			*customerGateway.CustomerGatewayId, err)
    87  	}
    88  
    89  	// Create tags.
    90  	if err := setTags(conn, d); err != nil {
    91  		return err
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func customerGatewayRefreshFunc(conn *ec2.EC2, gatewayId string) resource.StateRefreshFunc {
    98  	return func() (interface{}, string, error) {
    99  		gatewayFilter := &ec2.Filter{
   100  			Name:   aws.String("customer-gateway-id"),
   101  			Values: []*string{aws.String(gatewayId)},
   102  		}
   103  
   104  		resp, err := conn.DescribeCustomerGateways(&ec2.DescribeCustomerGatewaysInput{
   105  			Filters: []*ec2.Filter{gatewayFilter},
   106  		})
   107  		if err != nil {
   108  			if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidCustomerGatewayID.NotFound" {
   109  				resp = nil
   110  			} else {
   111  				log.Printf("Error on CustomerGatewayRefresh: %s", err)
   112  				return nil, "", err
   113  			}
   114  		}
   115  
   116  		if resp == nil || len(resp.CustomerGateways) == 0 {
   117  			// handle consistency issues
   118  			return nil, "", nil
   119  		}
   120  
   121  		gateway := resp.CustomerGateways[0]
   122  		return gateway, *gateway.State, nil
   123  	}
   124  }
   125  
   126  func resourceAwsCustomerGatewayRead(d *schema.ResourceData, meta interface{}) error {
   127  	conn := meta.(*AWSClient).ec2conn
   128  
   129  	gatewayFilter := &ec2.Filter{
   130  		Name:   aws.String("customer-gateway-id"),
   131  		Values: []*string{aws.String(d.Id())},
   132  	}
   133  
   134  	resp, err := conn.DescribeCustomerGateways(&ec2.DescribeCustomerGatewaysInput{
   135  		Filters: []*ec2.Filter{gatewayFilter},
   136  	})
   137  	if err != nil {
   138  		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidCustomerGatewayID.NotFound" {
   139  			d.SetId("")
   140  			return nil
   141  		} else {
   142  			log.Printf("[ERROR] Error finding CustomerGateway: %s", err)
   143  			return err
   144  		}
   145  	}
   146  
   147  	if len(resp.CustomerGateways) != 1 {
   148  		return fmt.Errorf("[ERROR] Error finding CustomerGateway: %s", d.Id())
   149  	}
   150  
   151  	if *resp.CustomerGateways[0].State == "deleted" {
   152  		log.Printf("[INFO] Customer Gateway is in `deleted` state: %s", d.Id())
   153  		d.SetId("")
   154  		return nil
   155  	}
   156  
   157  	customerGateway := resp.CustomerGateways[0]
   158  	d.Set("ip_address", customerGateway.IpAddress)
   159  	d.Set("type", customerGateway.Type)
   160  	d.Set("tags", tagsToMap(customerGateway.Tags))
   161  
   162  	if *customerGateway.BgpAsn != "" {
   163  		val, err := strconv.ParseInt(*customerGateway.BgpAsn, 0, 0)
   164  		if err != nil {
   165  			return fmt.Errorf("error parsing bgp_asn: %s", err)
   166  		}
   167  
   168  		d.Set("bgp_asn", int(val))
   169  	}
   170  
   171  	return nil
   172  }
   173  
   174  func resourceAwsCustomerGatewayUpdate(d *schema.ResourceData, meta interface{}) error {
   175  	conn := meta.(*AWSClient).ec2conn
   176  
   177  	// Update tags if required.
   178  	if err := setTags(conn, d); err != nil {
   179  		return err
   180  	}
   181  
   182  	d.SetPartial("tags")
   183  
   184  	return resourceAwsCustomerGatewayRead(d, meta)
   185  }
   186  
   187  func resourceAwsCustomerGatewayDelete(d *schema.ResourceData, meta interface{}) error {
   188  	conn := meta.(*AWSClient).ec2conn
   189  
   190  	_, err := conn.DeleteCustomerGateway(&ec2.DeleteCustomerGatewayInput{
   191  		CustomerGatewayId: aws.String(d.Id()),
   192  	})
   193  	if err != nil {
   194  		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidCustomerGatewayID.NotFound" {
   195  			d.SetId("")
   196  			return nil
   197  		} else {
   198  			log.Printf("[ERROR] Error deleting CustomerGateway: %s", err)
   199  			return err
   200  		}
   201  	}
   202  
   203  	gatewayFilter := &ec2.Filter{
   204  		Name:   aws.String("customer-gateway-id"),
   205  		Values: []*string{aws.String(d.Id())},
   206  	}
   207  
   208  	err = resource.Retry(5*time.Minute, func() *resource.RetryError {
   209  		resp, err := conn.DescribeCustomerGateways(&ec2.DescribeCustomerGatewaysInput{
   210  			Filters: []*ec2.Filter{gatewayFilter},
   211  		})
   212  
   213  		if err != nil {
   214  			if awserr, ok := err.(awserr.Error); ok && awserr.Code() == "InvalidCustomerGatewayID.NotFound" {
   215  				return nil
   216  			}
   217  			return resource.NonRetryableError(err)
   218  		}
   219  
   220  		if len(resp.CustomerGateways) != 1 {
   221  			return resource.RetryableError(fmt.Errorf("[ERROR] Error finding CustomerGateway for delete: %s", d.Id()))
   222  		}
   223  
   224  		switch *resp.CustomerGateways[0].State {
   225  		case "pending", "available", "deleting":
   226  			return resource.RetryableError(fmt.Errorf("[DEBUG] Gateway (%s) in state (%s), retrying", d.Id(), *resp.CustomerGateways[0].State))
   227  		case "deleted":
   228  			return nil
   229  		default:
   230  			return resource.RetryableError(fmt.Errorf("[DEBUG] Unrecognized state (%s) for Customer Gateway delete on (%s)", *resp.CustomerGateways[0].State, d.Id()))
   231  		}
   232  	})
   233  
   234  	if err != nil {
   235  		return err
   236  	}
   237  
   238  	return nil
   239  }