diff --git a/builtin/providers/aws/config.go b/builtin/providers/aws/config.go index 8bc9adab5..672af6f07 100644 --- a/builtin/providers/aws/config.go +++ b/builtin/providers/aws/config.go @@ -3,21 +3,16 @@ package aws import ( "fmt" "log" - "strings" - "unicode" "github.com/hashicorp/terraform/helper/multierror" - "github.com/mitchellh/goamz/aws" - "github.com/mitchellh/goamz/ec2" - awsGo "github.com/hashicorp/aws-sdk-go/aws" + "github.com/hashicorp/aws-sdk-go/aws" "github.com/hashicorp/aws-sdk-go/gen/autoscaling" + "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/aws-sdk-go/gen/elb" "github.com/hashicorp/aws-sdk-go/gen/rds" "github.com/hashicorp/aws-sdk-go/gen/route53" "github.com/hashicorp/aws-sdk-go/gen/s3" - - awsEC2 "github.com/hashicorp/aws-sdk-go/gen/ec2" ) type Config struct { @@ -29,7 +24,6 @@ type Config struct { type AWSClient struct { ec2conn *ec2.EC2 - awsEC2conn *awsEC2.EC2 elbconn *elb.ELB autoscalingconn *autoscaling.AutoScaling s3conn *s3.S3 @@ -45,14 +39,9 @@ func (c *Config) Client() (interface{}, error) { // Get the auth and region. This can fail if keys/regions were not // specified and we're attempting to use the environment. var errs []error - log.Println("[INFO] Building AWS auth structure") - auth, err := c.AWSAuth() - if err != nil { - errs = append(errs, err) - } log.Println("[INFO] Building AWS region structure") - region, err := c.AWSRegion() + err := c.ValidateRegion() if err != nil { errs = append(errs, err) } @@ -62,10 +51,9 @@ func (c *Config) Client() (interface{}, error) { // bucket storage in S3 client.region = c.Region - creds := awsGo.Creds(c.AccessKey, c.SecretKey, c.Token) + log.Println("[INFO] Building AWS auth structure") + creds := aws.Creds(c.AccessKey, c.SecretKey, c.Token) - log.Println("[INFO] Initializing EC2 connection") - client.ec2conn = ec2.New(auth, region) log.Println("[INFO] Initializing ELB connection") client.elbconn = elb.New(creds, c.Region, nil) log.Println("[INFO] Initializing AutoScaling connection") @@ -80,8 +68,8 @@ func (c *Config) Client() (interface{}, error) { // See http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html log.Println("[INFO] Initializing Route53 connection") client.r53conn = route53.New(creds, "us-east-1", nil) - log.Println("[INFO] Initializing AWS-GO EC2 Connection") - client.awsEC2conn = awsEC2.New(creds, c.Region, nil) + log.Println("[INFO] Initializing EC2 Connection") + client.ec2conn = ec2.New(creds, c.Region, nil) } if len(errs) > 0 { @@ -91,54 +79,17 @@ func (c *Config) Client() (interface{}, error) { return &client, nil } -// AWSAuth returns a valid aws.Auth object for access to AWS services, or -// an error if the authentication couldn't be resolved. -// -// TODO(mitchellh): Test in some way. -func (c *Config) AWSAuth() (aws.Auth, error) { - auth, err := aws.GetAuth(c.AccessKey, c.SecretKey) - if err == nil { - // Store the accesskey and secret that we got... - c.AccessKey = auth.AccessKey - c.SecretKey = auth.SecretKey - c.Token = auth.Token - } - - return auth, err -} - // IsValidRegion returns true if the configured region is a valid AWS // region and false if it's not -func (c *Config) IsValidRegion() bool { +func (c *Config) ValidateRegion() error { var regions = [11]string{"us-east-1", "us-west-2", "us-west-1", "eu-west-1", "eu-central-1", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", "sa-east-1", "cn-north-1", "us-gov-west-1"} for _, valid := range regions { if c.Region == valid { - return true + return nil } } - return false -} - -// AWSRegion returns the configured region. -// -// TODO(mitchellh): Test in some way. -func (c *Config) AWSRegion() (aws.Region, error) { - if c.Region != "" { - if c.IsValidRegion() { - return aws.Regions[c.Region], nil - } else { - return aws.Region{}, fmt.Errorf("Not a valid region: %s", c.Region) - } - } - - md, err := aws.GetMetaData("placement/availability-zone") - if err != nil { - return aws.Region{}, err - } - - region := strings.TrimRightFunc(string(md), unicode.IsLetter) - return aws.Regions[region], nil + return fmt.Errorf("Not a valid region: %s", c.Region) } diff --git a/builtin/providers/aws/resource_aws_db_parameter_group.go b/builtin/providers/aws/resource_aws_db_parameter_group.go index cf40d3b26..68c5b52e6 100644 --- a/builtin/providers/aws/resource_aws_db_parameter_group.go +++ b/builtin/providers/aws/resource_aws_db_parameter_group.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "log" + "strings" "time" "github.com/hashicorp/terraform/helper/hashcode" @@ -152,7 +153,7 @@ func resourceAwsDbParameterGroupUpdate(d *schema.ResourceData, meta interface{}) os := o.(*schema.Set) ns := n.(*schema.Set) - // Expand the "parameter" set to goamz compat []rds.Parameter + // Expand the "parameter" set to aws-sdk-go compat []rds.Parameter parameters, err := expandParameters(ns.Difference(os).List()) if err != nil { return err @@ -220,7 +221,8 @@ func resourceAwsDbParameterHash(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) - buf.WriteString(fmt.Sprintf("%s-", m["value"].(string))) + // Store the value as a lower case string, to match how we store them in flattenParameters + buf.WriteString(fmt.Sprintf("%s-", strings.ToLower(m["value"].(string)))) return hashcode.String(buf.String()) } diff --git a/builtin/providers/aws/resource_aws_eip.go b/builtin/providers/aws/resource_aws_eip.go index 103f9bc5a..c78fec4c9 100644 --- a/builtin/providers/aws/resource_aws_eip.go +++ b/builtin/providers/aws/resource_aws_eip.go @@ -60,7 +60,7 @@ func resourceAwsEip() *schema.Resource { } func resourceAwsEipCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // By default, we're not in a VPC domainOpt := "" @@ -97,7 +97,7 @@ func resourceAwsEipCreate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn domain := resourceAwsEipDomain(d) id := d.Id() @@ -148,7 +148,7 @@ func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error { } func resourceAwsEipUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn domain := resourceAwsEipDomain(d) @@ -181,7 +181,7 @@ func resourceAwsEipUpdate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsEipDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn if err := resourceAwsEipRead(d, meta); err != nil { return err diff --git a/builtin/providers/aws/resource_aws_eip_test.go b/builtin/providers/aws/resource_aws_eip_test.go index 79e88b8f3..b9944366f 100644 --- a/builtin/providers/aws/resource_aws_eip_test.go +++ b/builtin/providers/aws/resource_aws_eip_test.go @@ -58,7 +58,7 @@ func TestAccAWSEIP_instance(t *testing.T) { } func testAccCheckAWSEIPDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_eip" { @@ -113,7 +113,7 @@ func testAccCheckAWSEIPExists(n string, res *ec2.Address) resource.TestCheckFunc return fmt.Errorf("No EIP ID is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn if strings.Contains(rs.Primary.ID, "eipalloc") { req := &ec2.DescribeAddressesRequest{ diff --git a/builtin/providers/aws/resource_aws_elb.go b/builtin/providers/aws/resource_aws_elb.go index e5ed9f3cf..7898f2120 100644 --- a/builtin/providers/aws/resource_aws_elb.go +++ b/builtin/providers/aws/resource_aws_elb.go @@ -161,7 +161,7 @@ func resourceAwsElb() *schema.Resource { func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error { elbconn := meta.(*AWSClient).elbconn - // Expand the "listener" set to goamz compat []elb.Listener + // Expand the "listener" set to aws-sdk-go compat []elb.Listener listeners, err := expandListeners(d.Get("listener").(*schema.Set).List()) if err != nil { return err diff --git a/builtin/providers/aws/resource_aws_instance.go b/builtin/providers/aws/resource_aws_instance.go index 5475e7454..4e966e3b6 100644 --- a/builtin/providers/aws/resource_aws_instance.go +++ b/builtin/providers/aws/resource_aws_instance.go @@ -3,6 +3,7 @@ package aws import ( "bytes" "crypto/sha1" + "encoding/base64" "encoding/hex" "fmt" "log" @@ -253,17 +254,19 @@ func resourceAwsInstance() *schema.Resource { } func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Figure out user data userData := "" if v := d.Get("user_data"); v != nil { - userData = v.(string) + userData = base64.StdEncoding.EncodeToString([]byte(v.(string))) } placement := &ec2.Placement{ AvailabilityZone: aws.String(d.Get("availability_zone").(string)), - Tenancy: aws.String(d.Get("tenancy").(string)), + } + if v := d.Get("tenancy").(string); v != "" { + placement.Tenancy = aws.String(v) } iam := &ec2.IAMInstanceProfileSpecification{ @@ -292,6 +295,17 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { subnet, hasSubnet := d.GetOk("subnet_id") subnetID := subnet.(string) + var groups []string + if v := d.Get("security_groups"); v != nil { + // Security group names. + // For a nondefault VPC, you must use security group IDs instead. + // See http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html + for _, v := range v.(*schema.Set).List() { + str := v.(string) + groups = append(groups, str) + } + } + if hasSubnet && associatePublicIPAddress { // If we have a non-default VPC / Subnet specified, we can flag // AssociatePublicIpAddress to get a Public IP assigned. By default these are not provided. @@ -310,6 +324,10 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { ni.PrivateIPAddress = aws.String(v.(string)) } + if len(groups) > 0 { + ni.Groups = groups + } + runOpts.NetworkInterfaces = []ec2.InstanceNetworkInterfaceSpecification{ni} } else { if subnetID != "" { @@ -319,21 +337,6 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { if v, ok := d.GetOk("private_ip"); ok { runOpts.PrivateIPAddress = aws.String(v.(string)) } - } - - if v, ok := d.GetOk("key_name"); ok { - runOpts.KeyName = aws.String(v.(string)) - } - - if v := d.Get("security_groups"); v != nil { - // Security group names. - // For a nondefault VPC, you must use security group IDs instead. - // See http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html - var groups []string - for _, v := range v.(*schema.Set).List() { - str := v.(string) - groups = append(groups, str) - } if runOpts.SubnetID != nil && *runOpts.SubnetID != "" { runOpts.SecurityGroupIDs = groups @@ -342,6 +345,10 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } } + if v, ok := d.GetOk("key_name"); ok { + runOpts.KeyName = aws.String(v.(string)) + } + blockDevices := make([]interface{}, 0) if v := d.Get("block_device"); v != nil { @@ -437,7 +444,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn resp, err := ec2conn.DescribeInstances(&ec2.DescribeInstancesRequest{ InstanceIDs: []string{d.Id()}, @@ -481,7 +488,7 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { d.Set("subnet_id", instance.SubnetID) } d.Set("ebs_optimized", instance.EBSOptimized) - d.Set("tags", tagsToMapSDK(instance.Tags)) + d.Set("tags", tagsToMap(instance.Tags)) d.Set("tenancy", instance.Placement.Tenancy) // Determine whether we're referring to security groups with @@ -489,7 +496,7 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { // we use IDs if we're in a VPC. However, if we previously had an // all-name list of security groups, we use names. Or, if we had any // IDs, we use IDs. - useID := *instance.SubnetID != "" + useID := instance.SubnetID != nil && *instance.SubnetID != "" if v := d.Get("security_groups"); v != nil { match := false for _, v := range v.(*schema.Set).List() { @@ -561,25 +568,26 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error { } func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn - opts := new(ec2.ModifyInstanceAttributeRequest) + ec2conn := meta.(*AWSClient).ec2conn - log.Printf("[INFO] Modifying instance %s: %#v", d.Id(), opts) - err := ec2conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeRequest{ - InstanceID: aws.String(d.Id()), - SourceDestCheck: &ec2.AttributeBooleanValue{ - Value: aws.Boolean(d.Get("source_dest_check").(bool)), - }, - }) - - if err != nil { - return err + // SourceDestCheck can only be set on VPC instances + if d.Get("subnet_id").(string) != "" { + log.Printf("[INFO] Modifying instance %s", d.Id()) + err := ec2conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeRequest{ + InstanceID: aws.String(d.Id()), + SourceDestCheck: &ec2.AttributeBooleanValue{ + Value: aws.Boolean(d.Get("source_dest_check").(bool)), + }, + }) + if err != nil { + return err + } } // TODO(mitchellh): wait for the attributes we modified to // persist the change... - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } else { d.SetPartial("tags") @@ -589,7 +597,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsInstanceDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf("[INFO] Terminating instance: %s", d.Id()) req := &ec2.TerminateInstancesRequest{ diff --git a/builtin/providers/aws/resource_aws_instance_test.go b/builtin/providers/aws/resource_aws_instance_test.go index 3a9c16588..941dd5dd4 100644 --- a/builtin/providers/aws/resource_aws_instance_test.go +++ b/builtin/providers/aws/resource_aws_instance_test.go @@ -44,7 +44,7 @@ func TestAccAWSInstance_normal(t *testing.T) { resource.TestCheckResourceAttr( "aws_instance.foo", "user_data", - "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), + "3dc39dda39be1205215e776bad998da361a5955d"), ), }, @@ -60,7 +60,7 @@ func TestAccAWSInstance_normal(t *testing.T) { resource.TestCheckResourceAttr( "aws_instance.foo", "user_data", - "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), + "3dc39dda39be1205215e776bad998da361a5955d"), ), }, }, @@ -207,6 +207,25 @@ func TestAccAWSInstance_vpc(t *testing.T) { }) } +func TestAccInstance_NetworkInstanceSecurityGroups(t *testing.T) { + var v ec2.Instance + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccInstanceNetworkInstanceSecurityGroups, + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists( + "aws_instance.foo_instance", &v), + ), + }, + }, + }) +} + func TestAccAWSInstance_tags(t *testing.T) { var v ec2.Instance @@ -219,9 +238,9 @@ func TestAccAWSInstance_tags(t *testing.T) { Config: testAccCheckInstanceConfigTags, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.foo", &v), - testAccCheckTagsSDK(&v.Tags, "foo", "bar"), + testAccCheckTags(&v.Tags, "foo", "bar"), // Guard against regression of https://github.com/hashicorp/terraform/issues/914 - testAccCheckTagsSDK(&v.Tags, "#", ""), + testAccCheckTags(&v.Tags, "#", ""), ), }, @@ -229,8 +248,8 @@ func TestAccAWSInstance_tags(t *testing.T) { Config: testAccCheckInstanceConfigTagsUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.foo", &v), - testAccCheckTagsSDK(&v.Tags, "foo", ""), - testAccCheckTagsSDK(&v.Tags, "bar", "baz"), + testAccCheckTags(&v.Tags, "foo", ""), + testAccCheckTags(&v.Tags, "bar", "baz"), ), }, }, @@ -296,7 +315,7 @@ func TestAccAWSInstance_associatePublicIPAndPrivateIP(t *testing.T) { } func testAccCheckInstanceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_instance" { @@ -339,7 +358,7 @@ func testAccCheckInstanceExists(n string, i *ec2.Instance) resource.TestCheckFun return fmt.Errorf("No ID is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeInstances(&ec2.DescribeInstancesRequest{ InstanceIDs: []string{rs.Primary.ID}, }) @@ -392,7 +411,7 @@ resource "aws_instance" "foo" { instance_type = "m1.small" security_groups = ["${aws_security_group.tf_test_foo.name}"] - user_data = "foo" + user_data = "foo:-with-character's" } ` @@ -533,3 +552,49 @@ resource "aws_instance" "foo" { private_ip = "10.1.1.42" } ` + +const testAccInstanceNetworkInstanceSecurityGroups = ` +resource "aws_internet_gateway" "gw" { + vpc_id = "${aws_vpc.foo.id}" +} + +resource "aws_vpc" "foo" { + cidr_block = "10.1.0.0/16" + tags { + Name = "tf-network-test" + } +} + +resource "aws_security_group" "tf_test_foo" { + name = "tf_test_foo" + description = "foo" + vpc_id="${aws_vpc.foo.id}" + + ingress { + protocol = "icmp" + from_port = -1 + to_port = -1 + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_subnet" "foo" { + cidr_block = "10.1.1.0/24" + vpc_id = "${aws_vpc.foo.id}" +} + +resource "aws_instance" "foo_instance" { + ami = "ami-21f78e11" + instance_type = "t1.micro" + security_groups = ["${aws_security_group.tf_test_foo.id}"] + subnet_id = "${aws_subnet.foo.id}" + associate_public_ip_address = true + depends_on = ["aws_internet_gateway.gw"] +} + +resource "aws_eip" "foo_eip" { + instance = "${aws_instance.foo_instance.id}" + vpc = true + depends_on = ["aws_internet_gateway.gw"] +} +` diff --git a/builtin/providers/aws/resource_aws_internet_gateway.go b/builtin/providers/aws/resource_aws_internet_gateway.go index 499a20ed3..9546ffb5c 100644 --- a/builtin/providers/aws/resource_aws_internet_gateway.go +++ b/builtin/providers/aws/resource_aws_internet_gateway.go @@ -29,7 +29,7 @@ func resourceAwsInternetGateway() *schema.Resource { } func resourceAwsInternetGatewayCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Create the gateway log.Printf("[DEBUG] Creating internet gateway") @@ -43,7 +43,7 @@ func resourceAwsInternetGatewayCreate(d *schema.ResourceData, meta interface{}) d.SetId(*ig.InternetGatewayID) log.Printf("[INFO] InternetGateway ID: %s", d.Id()) - err = setTagsSDK(ec2conn, d) + err = setTags(ec2conn, d) if err != nil { return err } @@ -53,7 +53,7 @@ func resourceAwsInternetGatewayCreate(d *schema.ResourceData, meta interface{}) } func resourceAwsInternetGatewayRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn igRaw, _, err := IGStateRefreshFunc(ec2conn, d.Id())() if err != nil { @@ -73,7 +73,7 @@ func resourceAwsInternetGatewayRead(d *schema.ResourceData, meta interface{}) er d.Set("vpc_id", ig.Attachments[0].VPCID) } - d.Set("tags", tagsToMapSDK(ig.Tags)) + d.Set("tags", tagsToMap(ig.Tags)) return nil } @@ -91,9 +91,9 @@ func resourceAwsInternetGatewayUpdate(d *schema.ResourceData, meta interface{}) } } - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } @@ -103,7 +103,7 @@ func resourceAwsInternetGatewayUpdate(d *schema.ResourceData, meta interface{}) } func resourceAwsInternetGatewayDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Detach if it is attached if err := resourceAwsInternetGatewayDetach(d, meta); err != nil { @@ -137,7 +137,7 @@ func resourceAwsInternetGatewayDelete(d *schema.ResourceData, meta interface{}) } func resourceAwsInternetGatewayAttach(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn if d.Get("vpc_id").(string) == "" { log.Printf( @@ -182,7 +182,7 @@ func resourceAwsInternetGatewayAttach(d *schema.ResourceData, meta interface{}) } func resourceAwsInternetGatewayDetach(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Get the old VPC ID to detach from vpcID, _ := d.GetChange("vpc_id") diff --git a/builtin/providers/aws/resource_aws_internet_gateway_test.go b/builtin/providers/aws/resource_aws_internet_gateway_test.go index 26929f466..a07d1abff 100644 --- a/builtin/providers/aws/resource_aws_internet_gateway_test.go +++ b/builtin/providers/aws/resource_aws_internet_gateway_test.go @@ -98,7 +98,7 @@ func TestAccInternetGateway_tags(t *testing.T) { Config: testAccCheckInternetGatewayConfigTags, Check: resource.ComposeTestCheckFunc( testAccCheckInternetGatewayExists("aws_internet_gateway.foo", &v), - testAccCheckTagsSDK(&v.Tags, "foo", "bar"), + testAccCheckTags(&v.Tags, "foo", "bar"), ), }, @@ -106,8 +106,8 @@ func TestAccInternetGateway_tags(t *testing.T) { Config: testAccCheckInternetGatewayConfigTagsUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckInternetGatewayExists("aws_internet_gateway.foo", &v), - testAccCheckTagsSDK(&v.Tags, "foo", ""), - testAccCheckTagsSDK(&v.Tags, "bar", "baz"), + testAccCheckTags(&v.Tags, "foo", ""), + testAccCheckTags(&v.Tags, "bar", "baz"), ), }, }, @@ -115,7 +115,7 @@ func TestAccInternetGateway_tags(t *testing.T) { } func testAccCheckInternetGatewayDestroy(s *terraform.State) error { - ec2conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_internet_gateway" { @@ -158,7 +158,7 @@ func testAccCheckInternetGatewayExists(n string, ig *ec2.InternetGateway) resour return fmt.Errorf("No ID is set") } - ec2conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := ec2conn.DescribeInternetGateways(&ec2.DescribeInternetGatewaysRequest{ InternetGatewayIDs: []string{rs.Primary.ID}, }) diff --git a/builtin/providers/aws/resource_aws_key_pair.go b/builtin/providers/aws/resource_aws_key_pair.go index 573a93567..e96ecf620 100644 --- a/builtin/providers/aws/resource_aws_key_pair.go +++ b/builtin/providers/aws/resource_aws_key_pair.go @@ -37,7 +37,7 @@ func resourceAwsKeyPair() *schema.Resource { } func resourceAwsKeyPairCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn keyName := d.Get("key_name").(string) publicKey := d.Get("public_key").(string) @@ -55,7 +55,7 @@ func resourceAwsKeyPairCreate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsKeyPairRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn req := &ec2.DescribeKeyPairsRequest{ KeyNames: []string{d.Id()}, @@ -77,7 +77,7 @@ func resourceAwsKeyPairRead(d *schema.ResourceData, meta interface{}) error { } func resourceAwsKeyPairDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn err := ec2conn.DeleteKeyPair(&ec2.DeleteKeyPairRequest{ KeyName: aws.String(d.Id()), diff --git a/builtin/providers/aws/resource_aws_key_pair_test.go b/builtin/providers/aws/resource_aws_key_pair_test.go index b601d479a..695da661f 100644 --- a/builtin/providers/aws/resource_aws_key_pair_test.go +++ b/builtin/providers/aws/resource_aws_key_pair_test.go @@ -30,7 +30,7 @@ func TestAccAWSKeyPair_normal(t *testing.T) { } func testAccCheckAWSKeyPairDestroy(s *terraform.State) error { - ec2conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_key_pair" { @@ -81,7 +81,7 @@ func testAccCheckAWSKeyPairExists(n string, res *ec2.KeyPairInfo) resource.TestC return fmt.Errorf("No KeyPair name is set") } - ec2conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + ec2conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := ec2conn.DescribeKeyPairs(&ec2.DescribeKeyPairsRequest{ KeyNames: []string{rs.Primary.ID}, diff --git a/builtin/providers/aws/resource_aws_main_route_table_association.go b/builtin/providers/aws/resource_aws_main_route_table_association.go index a489b9a50..40303ab1e 100644 --- a/builtin/providers/aws/resource_aws_main_route_table_association.go +++ b/builtin/providers/aws/resource_aws_main_route_table_association.go @@ -40,7 +40,7 @@ func resourceAwsMainRouteTableAssociation() *schema.Resource { } func resourceAwsMainRouteTableAssociationCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn vpcId := d.Get("vpc_id").(string) routeTableId := d.Get("route_table_id").(string) @@ -67,7 +67,7 @@ func resourceAwsMainRouteTableAssociationCreate(d *schema.ResourceData, meta int } func resourceAwsMainRouteTableAssociationRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn mainAssociation, err := findMainRouteTableAssociation( ec2conn, @@ -88,7 +88,7 @@ func resourceAwsMainRouteTableAssociationRead(d *schema.ResourceData, meta inter // original_route_table_id - this needs to stay recorded as the AWS-created // table from VPC creation. func resourceAwsMainRouteTableAssociationUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn vpcId := d.Get("vpc_id").(string) routeTableId := d.Get("route_table_id").(string) @@ -109,7 +109,7 @@ func resourceAwsMainRouteTableAssociationUpdate(d *schema.ResourceData, meta int } func resourceAwsMainRouteTableAssociationDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn vpcId := d.Get("vpc_id").(string) originalRouteTableId := d.Get("original_route_table_id").(string) diff --git a/builtin/providers/aws/resource_aws_main_route_table_association_test.go b/builtin/providers/aws/resource_aws_main_route_table_association_test.go index 76e3e4d72..81f87a901 100644 --- a/builtin/providers/aws/resource_aws_main_route_table_association_test.go +++ b/builtin/providers/aws/resource_aws_main_route_table_association_test.go @@ -65,7 +65,7 @@ func testAccCheckMainRouteTableAssociation( return fmt.Errorf("Not found: %s", vpcResource) } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn mainAssociation, err := findMainRouteTableAssociation(conn, vpc.Primary.ID) if err != nil { return err diff --git a/builtin/providers/aws/resource_aws_network_acl.go b/builtin/providers/aws/resource_aws_network_acl.go index a8f654db7..0d625ffe4 100644 --- a/builtin/providers/aws/resource_aws_network_acl.go +++ b/builtin/providers/aws/resource_aws_network_acl.go @@ -109,7 +109,7 @@ func resourceAwsNetworkAcl() *schema.Resource { func resourceAwsNetworkAclCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Create the Network Acl createOpts := &ec2.CreateNetworkACLRequest{ @@ -132,7 +132,7 @@ func resourceAwsNetworkAclCreate(d *schema.ResourceData, meta interface{}) error } func resourceAwsNetworkAclRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn resp, err := ec2conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsRequest{ NetworkACLIDs: []string{d.Id()}, @@ -161,13 +161,13 @@ func resourceAwsNetworkAclRead(d *schema.ResourceData, meta interface{}) error { d.Set("vpc_id", networkAcl.VPCID) d.Set("ingress", ingressEntries) d.Set("egress", egressEntries) - d.Set("tags", tagsToMapSDK(networkAcl.Tags)) + d.Set("tags", tagsToMap(networkAcl.Tags)) return nil } func resourceAwsNetworkAclUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn d.Partial(true) if d.HasChange("ingress") { @@ -202,7 +202,7 @@ func resourceAwsNetworkAclUpdate(d *schema.ResourceData, meta interface{}) error } } - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } else { d.SetPartial("tags") @@ -265,7 +265,7 @@ func updateNetworkAclEntries(d *schema.ResourceData, entryType string, ec2conn * } func resourceAwsNetworkAclDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf("[INFO] Deleting Network Acl: %s", d.Id()) return resource.Retry(5*time.Minute, func() error { diff --git a/builtin/providers/aws/resource_aws_network_acl_test.go b/builtin/providers/aws/resource_aws_network_acl_test.go index a4183a1a1..23c60db44 100644 --- a/builtin/providers/aws/resource_aws_network_acl_test.go +++ b/builtin/providers/aws/resource_aws_network_acl_test.go @@ -151,7 +151,7 @@ func TestAccAWSNetworkAclsOnlyEgressRules(t *testing.T) { Config: testAccAWSNetworkAclEgressConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSNetworkAclExists("aws_network_acl.bond", &networkAcl), - testAccCheckTagsSDK(&networkAcl.Tags, "foo", "bar"), + testAccCheckTags(&networkAcl.Tags, "foo", "bar"), ), }, }, @@ -184,7 +184,7 @@ func TestAccAWSNetworkAcl_SubnetChange(t *testing.T) { } func testAccCheckAWSNetworkAclDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_network" { @@ -226,7 +226,7 @@ func testAccCheckAWSNetworkAclExists(n string, networkAcl *ec2.NetworkACL) resou if rs.Primary.ID == "" { return fmt.Errorf("No Security Group is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsRequest{ NetworkACLIDs: []string{rs.Primary.ID}, @@ -266,7 +266,7 @@ func testAccCheckSubnetIsAssociatedWithAcl(acl string, sub string) resource.Test networkAcl := s.RootModule().Resources[acl] subnet := s.RootModule().Resources[sub] - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsRequest{ NetworkACLIDs: []string{networkAcl.Primary.ID}, Filters: []ec2.Filter{ @@ -296,7 +296,7 @@ func testAccCheckSubnetIsNotAssociatedWithAcl(acl string, subnet string) resourc networkAcl := s.RootModule().Resources[acl] subnet := s.RootModule().Resources[subnet] - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeNetworkACLs(&ec2.DescribeNetworkACLsRequest{ NetworkACLIDs: []string{networkAcl.Primary.ID}, Filters: []ec2.Filter{ diff --git a/builtin/providers/aws/resource_aws_route53_record.go b/builtin/providers/aws/resource_aws_route53_record.go index fcd781c61..abfa04942 100644 --- a/builtin/providers/aws/resource_aws_route53_record.go +++ b/builtin/providers/aws/resource_aws_route53_record.go @@ -173,7 +173,8 @@ func resourceAwsRoute53RecordRead(d *schema.ResourceData, meta interface{}) erro // Scan for a matching record found := false for _, record := range resp.ResourceRecordSets { - if FQDN(*record.Name) != FQDN(*lopts.StartRecordName) { + name := cleanRecordName(*record.Name) + if FQDN(name) != FQDN(*lopts.StartRecordName) { continue } if strings.ToUpper(*record.Type) != strings.ToUpper(*lopts.StartRecordType) { @@ -232,15 +233,17 @@ func resourceAwsRoute53RecordDelete(d *schema.ResourceData, meta interface{}) er Refresh: func() (interface{}, string, error) { _, err := conn.ChangeResourceRecordSets(req) if err != nil { - if strings.Contains(err.Error(), "PriorRequestNotComplete") { - // There is some pending operation, so just retry - // in a bit. - return 42, "rejected", nil - } + if r53err, ok := err.(aws.APIError); ok { + if r53err.Code == "PriorRequestNotComplete" { + // There is some pending operation, so just retry + // in a bit. + return 42, "rejected", nil + } - if strings.Contains(err.Error(), "InvalidChangeBatch") { - // This means that the record is already gone. - return 42, "accepted", nil + if r53err.Code == "InvalidChangeBatch" { + // This means that the record is already gone. + return 42, "accepted", nil + } } return 42, "failure", err @@ -282,3 +285,15 @@ func FQDN(name string) string { return name + "." } } + +// Route 53 stores the "*" wildcard indicator as ASCII 42 and returns the +// octal equivalent, "\\052". Here we look for that, and convert back to "*" +// as needed. +func cleanRecordName(name string) string { + str := name + if strings.HasPrefix(name, "\\052") { + str = strings.Replace(name, "\\052", "*", 1) + log.Printf("[DEBUG] Replacing octal \\052 for * in: %s", name) + } + return str +} diff --git a/builtin/providers/aws/resource_aws_route53_record_test.go b/builtin/providers/aws/resource_aws_route53_record_test.go index 08325c783..0608c51d1 100644 --- a/builtin/providers/aws/resource_aws_route53_record_test.go +++ b/builtin/providers/aws/resource_aws_route53_record_test.go @@ -9,9 +9,26 @@ import ( "github.com/hashicorp/terraform/terraform" "github.com/hashicorp/aws-sdk-go/aws" - awsr53 "github.com/hashicorp/aws-sdk-go/gen/route53" + route53 "github.com/hashicorp/aws-sdk-go/gen/route53" ) +func TestCleanRecordName(t *testing.T) { + cases := []struct { + Input, Output string + }{ + {"www.nonexample.com", "www.nonexample.com"}, + {"\\052.nonexample.com", "*.nonexample.com"}, + {"nonexample.com", "nonexample.com"}, + } + + for _, tc := range cases { + actual := cleanRecordName(tc.Input) + if actual != tc.Output { + t.Fatalf("input: %s\noutput: %s", tc.Input, actual) + } + } +} + func TestAccRoute53Record(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -44,6 +61,30 @@ func TestAccRoute53Record_generatesSuffix(t *testing.T) { }) } +func TestAccRoute53Record_wildcard(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53RecordDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccRoute53WildCardRecordConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53RecordExists("aws_route53_record.wildcard"), + ), + }, + + // Cause a change, which will trigger a refresh + resource.TestStep{ + Config: testAccRoute53WildCardRecordConfigUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53RecordExists("aws_route53_record.wildcard"), + ), + }, + }, + }) +} + func testAccCheckRoute53RecordDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).r53conn for _, rs := range s.RootModule().Resources { @@ -56,7 +97,7 @@ func testAccCheckRoute53RecordDestroy(s *terraform.State) error { name := parts[1] rType := parts[2] - lopts := &awsr53.ListResourceRecordSetsRequest{ + lopts := &route53.ListResourceRecordSetsRequest{ HostedZoneID: aws.String(cleanZoneID(zone)), StartRecordName: aws.String(name), StartRecordType: aws.String(rType), @@ -94,7 +135,7 @@ func testAccCheckRoute53RecordExists(n string) resource.TestCheckFunc { name := parts[1] rType := parts[2] - lopts := &awsr53.ListResourceRecordSetsRequest{ + lopts := &route53.ListResourceRecordSetsRequest{ HostedZoneID: aws.String(cleanZoneID(zone)), StartRecordName: aws.String(name), StartRecordType: aws.String(rType), @@ -107,11 +148,14 @@ func testAccCheckRoute53RecordExists(n string) resource.TestCheckFunc { if len(resp.ResourceRecordSets) == 0 { return fmt.Errorf("Record does not exist") } - rec := resp.ResourceRecordSets[0] - if FQDN(*rec.Name) == FQDN(name) && *rec.Type == rType { - return nil + // rec := resp.ResourceRecordSets[0] + for _, rec := range resp.ResourceRecordSets { + recName := cleanRecordName(*rec.Name) + if FQDN(recName) == FQDN(name) && *rec.Type == rType { + return nil + } } - return fmt.Errorf("Record does not exist: %#v", rec) + return fmt.Errorf("Record does not exist: %#v", rs.Primary.ID) } } @@ -142,3 +186,47 @@ resource "aws_route53_record" "default" { records = ["127.0.0.1", "127.0.0.27"] } ` + +const testAccRoute53WildCardRecordConfig = ` +resource "aws_route53_zone" "main" { + name = "notexample.com" +} + +resource "aws_route53_record" "default" { + zone_id = "${aws_route53_zone.main.zone_id}" + name = "subdomain" + type = "A" + ttl = "30" + records = ["127.0.0.1", "127.0.0.27"] +} + +resource "aws_route53_record" "wildcard" { + zone_id = "${aws_route53_zone.main.zone_id}" + name = "*.notexample.com" + type = "A" + ttl = "30" + records = ["127.0.0.1"] +} +` + +const testAccRoute53WildCardRecordConfigUpdate = ` +resource "aws_route53_zone" "main" { + name = "notexample.com" +} + +resource "aws_route53_record" "default" { + zone_id = "${aws_route53_zone.main.zone_id}" + name = "subdomain" + type = "A" + ttl = "30" + records = ["127.0.0.1", "127.0.0.27"] +} + +resource "aws_route53_record" "wildcard" { + zone_id = "${aws_route53_zone.main.zone_id}" + name = "*.notexample.com" + type = "A" + ttl = "60" + records = ["127.0.0.1"] +} +` diff --git a/builtin/providers/aws/resource_aws_route_table.go b/builtin/providers/aws/resource_aws_route_table.go index 0290d053f..6a4b1d3ca 100644 --- a/builtin/providers/aws/resource_aws_route_table.go +++ b/builtin/providers/aws/resource_aws_route_table.go @@ -62,7 +62,7 @@ func resourceAwsRouteTable() *schema.Resource { } func resourceAwsRouteTableCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Create the routing table createOpts := &ec2.CreateRouteTableRequest{ @@ -100,7 +100,7 @@ func resourceAwsRouteTableCreate(d *schema.ResourceData, meta interface{}) error } func resourceAwsRouteTableRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn rtRaw, _, err := resourceAwsRouteTableStateRefreshFunc(ec2conn, d.Id())() if err != nil { @@ -146,13 +146,13 @@ func resourceAwsRouteTableRead(d *schema.ResourceData, meta interface{}) error { d.Set("route", route) // Tags - d.Set("tags", tagsToMapSDK(rt.Tags)) + d.Set("tags", tagsToMap(rt.Tags)) return nil } func resourceAwsRouteTableUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Check if the route set as a whole has changed if d.HasChange("route") { @@ -203,7 +203,7 @@ func resourceAwsRouteTableUpdate(d *schema.ResourceData, meta interface{}) error } } - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } else { d.SetPartial("tags") @@ -213,7 +213,7 @@ func resourceAwsRouteTableUpdate(d *schema.ResourceData, meta interface{}) error } func resourceAwsRouteTableDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // First request the routing table since we'll have to disassociate // all the subnets first. diff --git a/builtin/providers/aws/resource_aws_route_table_association.go b/builtin/providers/aws/resource_aws_route_table_association.go index a9a614f7f..8fd324035 100644 --- a/builtin/providers/aws/resource_aws_route_table_association.go +++ b/builtin/providers/aws/resource_aws_route_table_association.go @@ -32,7 +32,7 @@ func resourceAwsRouteTableAssociation() *schema.Resource { } func resourceAwsRouteTableAssociationCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf( "[INFO] Creating route table association: %s => %s", @@ -56,7 +56,7 @@ func resourceAwsRouteTableAssociationCreate(d *schema.ResourceData, meta interfa } func resourceAwsRouteTableAssociationRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Get the routing table that this association belongs to rtRaw, _, err := resourceAwsRouteTableStateRefreshFunc( @@ -88,7 +88,7 @@ func resourceAwsRouteTableAssociationRead(d *schema.ResourceData, meta interface } func resourceAwsRouteTableAssociationUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf( "[INFO] Creating route table association: %s => %s", @@ -119,7 +119,7 @@ func resourceAwsRouteTableAssociationUpdate(d *schema.ResourceData, meta interfa } func resourceAwsRouteTableAssociationDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf("[INFO] Deleting route table association: %s", d.Id()) err := ec2conn.DisassociateRouteTable(&ec2.DisassociateRouteTableRequest{ diff --git a/builtin/providers/aws/resource_aws_route_table_association_test.go b/builtin/providers/aws/resource_aws_route_table_association_test.go index 8c4246aba..f5302258d 100644 --- a/builtin/providers/aws/resource_aws_route_table_association_test.go +++ b/builtin/providers/aws/resource_aws_route_table_association_test.go @@ -38,7 +38,7 @@ func TestAccAWSRouteTableAssociation(t *testing.T) { } func testAccCheckRouteTableAssociationDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_route_table_association" { @@ -83,7 +83,7 @@ func testAccCheckRouteTableAssociationExists(n string, v *ec2.RouteTable) resour return fmt.Errorf("No ID is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesRequest{ RouteTableIDs: []string{rs.Primary.Attributes["route_table_id"]}, }) diff --git a/builtin/providers/aws/resource_aws_route_table_test.go b/builtin/providers/aws/resource_aws_route_table_test.go index 5e6f90026..b428b8786 100644 --- a/builtin/providers/aws/resource_aws_route_table_test.go +++ b/builtin/providers/aws/resource_aws_route_table_test.go @@ -134,7 +134,7 @@ func TestAccAWSRouteTable_tags(t *testing.T) { Config: testAccRouteTableConfigTags, Check: resource.ComposeTestCheckFunc( testAccCheckRouteTableExists("aws_route_table.foo", &route_table), - testAccCheckTagsSDK(&route_table.Tags, "foo", "bar"), + testAccCheckTags(&route_table.Tags, "foo", "bar"), ), }, @@ -142,8 +142,8 @@ func TestAccAWSRouteTable_tags(t *testing.T) { Config: testAccRouteTableConfigTagsUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckRouteTableExists("aws_route_table.foo", &route_table), - testAccCheckTagsSDK(&route_table.Tags, "foo", ""), - testAccCheckTagsSDK(&route_table.Tags, "bar", "baz"), + testAccCheckTags(&route_table.Tags, "foo", ""), + testAccCheckTags(&route_table.Tags, "bar", "baz"), ), }, }, @@ -151,7 +151,7 @@ func TestAccAWSRouteTable_tags(t *testing.T) { } func testAccCheckRouteTableDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_route_table" { @@ -194,7 +194,7 @@ func testAccCheckRouteTableExists(n string, v *ec2.RouteTable) resource.TestChec return fmt.Errorf("No ID is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeRouteTables(&ec2.DescribeRouteTablesRequest{ RouteTableIDs: []string{rs.Primary.ID}, }) diff --git a/builtin/providers/aws/resource_aws_security_group.go b/builtin/providers/aws/resource_aws_security_group.go index b7addd9aa..4a74550e8 100644 --- a/builtin/providers/aws/resource_aws_security_group.go +++ b/builtin/providers/aws/resource_aws_security_group.go @@ -142,7 +142,7 @@ func resourceAwsSecurityGroup() *schema.Resource { } func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn securityGroupOpts := &ec2.CreateSecurityGroupRequest{ GroupName: aws.String(d.Get("name").(string)), @@ -187,7 +187,7 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er } func resourceAwsSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn sgRaw, _, err := SGStateRefreshFunc(ec2conn, d.Id())() if err != nil { @@ -209,12 +209,12 @@ func resourceAwsSecurityGroupRead(d *schema.ResourceData, meta interface{}) erro d.Set("owner_id", sg.OwnerID) d.Set("ingress", ingressRules) d.Set("egress", egressRules) - d.Set("tags", tagsToMapSDK(sg.Tags)) + d.Set("tags", tagsToMap(sg.Tags)) return nil } func resourceAwsSecurityGroupUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn sgRaw, _, err := SGStateRefreshFunc(ec2conn, d.Id())() if err != nil { @@ -239,7 +239,7 @@ func resourceAwsSecurityGroupUpdate(d *schema.ResourceData, meta interface{}) er } } - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } @@ -249,7 +249,7 @@ func resourceAwsSecurityGroupUpdate(d *schema.ResourceData, meta interface{}) er } func resourceAwsSecurityGroupDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf("[DEBUG] Security Group destroy: %v", d.Id()) @@ -285,6 +285,7 @@ func resourceAwsSecurityGroupRuleHash(v interface{}) int { buf.WriteString(fmt.Sprintf("%d-", m["from_port"].(int))) buf.WriteString(fmt.Sprintf("%d-", m["to_port"].(int))) buf.WriteString(fmt.Sprintf("%s-", m["protocol"].(string))) + buf.WriteString(fmt.Sprintf("%t-", m["self"].(bool))) // We need to make sure to sort the strings below so that we always // generate the same hash code no matter what is in the set. @@ -354,7 +355,7 @@ func resourceAwsSecurityGroupIPPermGather(d *schema.ResourceData, permissions [] var groups []string if len(perm.UserIDGroupPairs) > 0 { - groups = flattenSecurityGroupsSDK(perm.UserIDGroupPairs) + groups = flattenSecurityGroups(perm.UserIDGroupPairs) } for i, id := range groups { if id == d.Id() { @@ -396,9 +397,8 @@ func resourceAwsSecurityGroupUpdateRules( os := o.(*schema.Set) ns := n.(*schema.Set) - // TODO: re-munge this when test is updated - remove := expandIPPerms(d.Id(), os.Difference(ns).List()) - add := expandIPPerms(d.Id(), ns.Difference(os).List()) + remove := expandIPPerms(group, os.Difference(ns).List()) + add := expandIPPerms(group, ns.Difference(os).List()) // TODO: We need to handle partial state better in the in-between // in this update. @@ -410,7 +410,7 @@ func resourceAwsSecurityGroupUpdateRules( // not have service issues. if len(remove) > 0 || len(add) > 0 { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn var err error if len(remove) > 0 { @@ -453,6 +453,11 @@ func resourceAwsSecurityGroupUpdateRules( GroupID: group.GroupID, IPPermissions: add, } + if group.VPCID == nil || *group.VPCID == "" { + req.GroupID = nil + req.GroupName = group.GroupName + } + err = ec2conn.AuthorizeSecurityGroupIngress(req) } diff --git a/builtin/providers/aws/resource_aws_security_group_test.go b/builtin/providers/aws/resource_aws_security_group_test.go index c292c80d6..b1e4e8c82 100644 --- a/builtin/providers/aws/resource_aws_security_group_test.go +++ b/builtin/providers/aws/resource_aws_security_group_test.go @@ -186,7 +186,7 @@ func TestAccAWSSecurityGroup_Change(t *testing.T) { } func testAccCheckAWSSecurityGroupDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_security_group" { @@ -230,7 +230,7 @@ func testAccCheckAWSSecurityGroupExists(n string, group *ec2.SecurityGroup) reso return fmt.Errorf("No Security Group is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn req := &ec2.DescribeSecurityGroupsRequest{ GroupIDs: []string{rs.Primary.ID}, } @@ -296,7 +296,7 @@ func TestAccAWSSecurityGroup_tags(t *testing.T) { Config: testAccAWSSecurityGroupConfigTags, Check: resource.ComposeTestCheckFunc( testAccCheckAWSSecurityGroupExists("aws_security_group.foo", &group), - testAccCheckTagsSDK(&group.Tags, "foo", "bar"), + testAccCheckTags(&group.Tags, "foo", "bar"), ), }, @@ -304,8 +304,8 @@ func TestAccAWSSecurityGroup_tags(t *testing.T) { Config: testAccAWSSecurityGroupConfigTagsUpdate, Check: resource.ComposeTestCheckFunc( testAccCheckAWSSecurityGroupExists("aws_security_group.foo", &group), - testAccCheckTagsSDK(&group.Tags, "foo", ""), - testAccCheckTagsSDK(&group.Tags, "bar", "baz"), + testAccCheckTags(&group.Tags, "foo", ""), + testAccCheckTags(&group.Tags, "bar", "baz"), ), }, }, diff --git a/builtin/providers/aws/resource_aws_subnet.go b/builtin/providers/aws/resource_aws_subnet.go index e09fb8bc4..d1db5aed9 100644 --- a/builtin/providers/aws/resource_aws_subnet.go +++ b/builtin/providers/aws/resource_aws_subnet.go @@ -51,7 +51,7 @@ func resourceAwsSubnet() *schema.Resource { } func resourceAwsSubnetCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn createOpts := &ec2.CreateSubnetRequest{ AvailabilityZone: aws.String(d.Get("availability_zone").(string)), @@ -91,7 +91,7 @@ func resourceAwsSubnetCreate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn resp, err := ec2conn.DescribeSubnets(&ec2.DescribeSubnetsRequest{ SubnetIDs: []string{d.Id()}, @@ -115,17 +115,17 @@ func resourceAwsSubnetRead(d *schema.ResourceData, meta interface{}) error { d.Set("availability_zone", subnet.AvailabilityZone) d.Set("cidr_block", subnet.CIDRBlock) d.Set("map_public_ip_on_launch", subnet.MapPublicIPOnLaunch) - d.Set("tags", tagsToMapSDK(subnet.Tags)) + d.Set("tags", tagsToMap(subnet.Tags)) return nil } func resourceAwsSubnetUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn d.Partial(true) - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } else { d.SetPartial("tags") @@ -154,7 +154,7 @@ func resourceAwsSubnetUpdate(d *schema.ResourceData, meta interface{}) error { } func resourceAwsSubnetDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn log.Printf("[INFO] Deleting subnet: %s", d.Id()) diff --git a/builtin/providers/aws/resource_aws_subnet_test.go b/builtin/providers/aws/resource_aws_subnet_test.go index 77dfeccf0..ae7b28dee 100644 --- a/builtin/providers/aws/resource_aws_subnet_test.go +++ b/builtin/providers/aws/resource_aws_subnet_test.go @@ -43,7 +43,7 @@ func TestAccAWSSubnet(t *testing.T) { } func testAccCheckSubnetDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_subnet" { @@ -86,7 +86,7 @@ func testAccCheckSubnetExists(n string, v *ec2.Subnet) resource.TestCheckFunc { return fmt.Errorf("No ID is set") } - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn resp, err := conn.DescribeSubnets(&ec2.DescribeSubnetsRequest{ SubnetIDs: []string{rs.Primary.ID}, }) diff --git a/builtin/providers/aws/resource_aws_vpc.go b/builtin/providers/aws/resource_aws_vpc.go index f4ac2162e..0ef8aa570 100644 --- a/builtin/providers/aws/resource_aws_vpc.go +++ b/builtin/providers/aws/resource_aws_vpc.go @@ -5,9 +5,10 @@ import ( "log" "time" + "github.com/hashicorp/aws-sdk-go/aws" + "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" - "github.com/mitchellh/goamz/ec2" ) func resourceAwsVpc() *schema.Resource { @@ -64,22 +65,25 @@ func resourceAwsVpc() *schema.Resource { func resourceAwsVpcCreate(d *schema.ResourceData, meta interface{}) error { ec2conn := meta.(*AWSClient).ec2conn - - // Create the VPC - createOpts := &ec2.CreateVpc{ - CidrBlock: d.Get("cidr_block").(string), - InstanceTenancy: d.Get("instance_tenancy").(string), + instance_tenancy := "default" + if v, ok := d.GetOk("instance_tenancy"); ok { + instance_tenancy = v.(string) } - log.Printf("[DEBUG] VPC create config: %#v", createOpts) - vpcResp, err := ec2conn.CreateVpc(createOpts) + // Create the VPC + createOpts := &ec2.CreateVPCRequest{ + CIDRBlock: aws.String(d.Get("cidr_block").(string)), + InstanceTenancy: aws.String(instance_tenancy), + } + log.Printf("[DEBUG] VPC create config: %#v", *createOpts) + vpcResp, err := ec2conn.CreateVPC(createOpts) if err != nil { return fmt.Errorf("Error creating VPC: %s", err) } // Get the ID and store it - vpc := &vpcResp.VPC - log.Printf("[INFO] VPC ID: %s", vpc.VpcId) - d.SetId(vpc.VpcId) + vpc := vpcResp.VPC + d.SetId(*vpc.VPCID) + log.Printf("[INFO] VPC ID: %s", d.Id()) // Set partial mode and say that we setup the cidr block d.Partial(true) @@ -120,34 +124,53 @@ func resourceAwsVpcRead(d *schema.ResourceData, meta interface{}) error { // VPC stuff vpc := vpcRaw.(*ec2.VPC) - d.Set("cidr_block", vpc.CidrBlock) + vpcid := d.Id() + d.Set("cidr_block", vpc.CIDRBlock) // Tags d.Set("tags", tagsToMap(vpc.Tags)) // Attributes - resp, err := ec2conn.VpcAttribute(d.Id(), "enableDnsSupport") + attribute := "enableDnsSupport" + DescribeAttrOpts := &ec2.DescribeVPCAttributeRequest{ + Attribute: aws.String(attribute), + VPCID: aws.String(vpcid), + } + resp, err := ec2conn.DescribeVPCAttribute(DescribeAttrOpts) if err != nil { return err } - d.Set("enable_dns_support", resp.EnableDnsSupport) - - resp, err = ec2conn.VpcAttribute(d.Id(), "enableDnsHostnames") + d.Set("enable_dns_support", *resp.EnableDNSSupport) + attribute = "enableDnsHostnames" + DescribeAttrOpts = &ec2.DescribeVPCAttributeRequest{ + Attribute: &attribute, + VPCID: &vpcid, + } + resp, err = ec2conn.DescribeVPCAttribute(DescribeAttrOpts) if err != nil { return err } - d.Set("enable_dns_hostnames", resp.EnableDnsHostnames) + d.Set("enable_dns_hostnames", *resp.EnableDNSHostnames) // Get the main routing table for this VPC - filter := ec2.NewFilter() - filter.Add("association.main", "true") - filter.Add("vpc-id", d.Id()) - routeResp, err := ec2conn.DescribeRouteTables(nil, filter) + // Really Ugly need to make this better - rmenn + filter1 := &ec2.Filter{ + Name: aws.String("association.main"), + Values: []string{("true")}, + } + filter2 := &ec2.Filter{ + Name: aws.String("vpc-id"), + Values: []string{(d.Id())}, + } + DescribeRouteOpts := &ec2.DescribeRouteTablesRequest{ + Filters: []ec2.Filter{*filter1, *filter2}, + } + routeResp, err := ec2conn.DescribeRouteTables(DescribeRouteOpts) if err != nil { return err } if v := routeResp.RouteTables; len(v) > 0 { - d.Set("main_route_table_id", v[0].RouteTableId) + d.Set("main_route_table_id", *v[0].RouteTableID) } resourceAwsVpcSetDefaultNetworkAcl(ec2conn, d) @@ -161,16 +184,20 @@ func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error { // Turn on partial mode d.Partial(true) - + vpcid := d.Id() + modifyOpts := &ec2.ModifyVPCAttributeRequest{ + VPCID: &vpcid, + } if d.HasChange("enable_dns_hostnames") { - options := new(ec2.ModifyVpcAttribute) - options.EnableDnsHostnames = d.Get("enable_dns_hostnames").(bool) - options.SetEnableDnsHostnames = true + val := d.Get("enable_dns_hostnames").(bool) + modifyOpts.EnableDNSHostnames = &ec2.AttributeBooleanValue{ + Value: &val, + } log.Printf( "[INFO] Modifying enable_dns_hostnames vpc attribute for %s: %#v", - d.Id(), options) - if _, err := ec2conn.ModifyVpcAttribute(d.Id(), options); err != nil { + d.Id(), modifyOpts) + if err := ec2conn.ModifyVPCAttribute(modifyOpts); err != nil { return err } @@ -178,14 +205,15 @@ func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("enable_dns_support") { - options := new(ec2.ModifyVpcAttribute) - options.EnableDnsSupport = d.Get("enable_dns_support").(bool) - options.SetEnableDnsSupport = true + val := d.Get("enable_dns_hostnames").(bool) + modifyOpts.EnableDNSSupport = &ec2.AttributeBooleanValue{ + Value: &val, + } log.Printf( "[INFO] Modifying enable_dns_support vpc attribute for %s: %#v", - d.Id(), options) - if _, err := ec2conn.ModifyVpcAttribute(d.Id(), options); err != nil { + d.Id(), modifyOpts) + if err := ec2conn.ModifyVPCAttribute(modifyOpts); err != nil { return err } @@ -204,10 +232,13 @@ func resourceAwsVpcUpdate(d *schema.ResourceData, meta interface{}) error { func resourceAwsVpcDelete(d *schema.ResourceData, meta interface{}) error { ec2conn := meta.(*AWSClient).ec2conn - + vpcID := d.Id() + DeleteVpcOpts := &ec2.DeleteVPCRequest{ + VPCID: &vpcID, + } log.Printf("[INFO] Deleting VPC: %s", d.Id()) - if _, err := ec2conn.DeleteVpc(d.Id()); err != nil { - ec2err, ok := err.(*ec2.Error) + if err := ec2conn.DeleteVPC(DeleteVpcOpts); err != nil { + ec2err, ok := err.(*aws.APIError) if ok && ec2err.Code == "InvalidVpcID.NotFound" { return nil } @@ -222,9 +253,12 @@ func resourceAwsVpcDelete(d *schema.ResourceData, meta interface{}) error { // a VPC. func VPCStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - resp, err := conn.DescribeVpcs([]string{id}, ec2.NewFilter()) + DescribeVpcOpts := &ec2.DescribeVPCsRequest{ + VPCIDs: []string{id}, + } + resp, err := conn.DescribeVPCs(DescribeVpcOpts) if err != nil { - if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidVpcID.NotFound" { + if ec2err, ok := err.(*aws.APIError); ok && ec2err.Code == "InvalidVpcID.NotFound" { resp = nil } else { log.Printf("Error on VPCStateRefresh: %s", err) @@ -239,37 +273,53 @@ func VPCStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { } vpc := &resp.VPCs[0] - return vpc, vpc.State, nil + return vpc, *vpc.State, nil } } func resourceAwsVpcSetDefaultNetworkAcl(conn *ec2.EC2, d *schema.ResourceData) error { - filter := ec2.NewFilter() - filter.Add("default", "true") - filter.Add("vpc-id", d.Id()) - networkAclResp, err := conn.NetworkAcls(nil, filter) + filter1 := &ec2.Filter{ + Name: aws.String("default"), + Values: []string{("true")}, + } + filter2 := &ec2.Filter{ + Name: aws.String("vpc-id"), + Values: []string{(d.Id())}, + } + DescribeNetworkACLOpts := &ec2.DescribeNetworkACLsRequest{ + Filters: []ec2.Filter{*filter1, *filter2}, + } + networkAclResp, err := conn.DescribeNetworkACLs(DescribeNetworkACLOpts) if err != nil { return err } - if v := networkAclResp.NetworkAcls; len(v) > 0 { - d.Set("default_network_acl_id", v[0].NetworkAclId) + if v := networkAclResp.NetworkACLs; len(v) > 0 { + d.Set("default_network_acl_id", v[0].NetworkACLID) } return nil } func resourceAwsVpcSetDefaultSecurityGroup(conn *ec2.EC2, d *schema.ResourceData) error { - filter := ec2.NewFilter() - filter.Add("group-name", "default") - filter.Add("vpc-id", d.Id()) - securityGroupResp, err := conn.SecurityGroups(nil, filter) + filter1 := &ec2.Filter{ + Name: aws.String("group-name"), + Values: []string{("default")}, + } + filter2 := &ec2.Filter{ + Name: aws.String("vpc-id"), + Values: []string{(d.Id())}, + } + DescribeSgOpts := &ec2.DescribeSecurityGroupsRequest{ + Filters: []ec2.Filter{*filter1, *filter2}, + } + securityGroupResp, err := conn.DescribeSecurityGroups(DescribeSgOpts) if err != nil { return err } - if v := securityGroupResp.Groups; len(v) > 0 { - d.Set("default_security_group_id", v[0].Id) + if v := securityGroupResp.SecurityGroups; len(v) > 0 { + d.Set("default_security_group_id", v[0].GroupID) } return nil diff --git a/builtin/providers/aws/resource_aws_vpc_peering_connection.go b/builtin/providers/aws/resource_aws_vpc_peering_connection.go index 06f50f01c..0f8c6185b 100644 --- a/builtin/providers/aws/resource_aws_vpc_peering_connection.go +++ b/builtin/providers/aws/resource_aws_vpc_peering_connection.go @@ -41,7 +41,7 @@ func resourceAwsVpcPeeringConnection() *schema.Resource { } func resourceAwsVpcPeeringCreate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn // Create the vpc peering connection createOpts := &ec2.CreateVPCPeeringConnectionRequest{ @@ -80,7 +80,7 @@ func resourceAwsVpcPeeringCreate(d *schema.ResourceData, meta interface{}) error } func resourceAwsVpcPeeringRead(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn pcRaw, _, err := resourceAwsVpcPeeringConnectionStateRefreshFunc(ec2conn, d.Id())() if err != nil { return err @@ -95,15 +95,15 @@ func resourceAwsVpcPeeringRead(d *schema.ResourceData, meta interface{}) error { d.Set("peer_owner_id", pc.AccepterVPCInfo.OwnerID) d.Set("peer_vpc_id", pc.AccepterVPCInfo.VPCID) d.Set("vpc_id", pc.RequesterVPCInfo.VPCID) - d.Set("tags", tagsToMapSDK(pc.Tags)) + d.Set("tags", tagsToMap(pc.Tags)) return nil } func resourceAwsVpcPeeringUpdate(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn - if err := setTagsSDK(ec2conn, d); err != nil { + if err := setTags(ec2conn, d); err != nil { return err } else { d.SetPartial("tags") @@ -113,7 +113,7 @@ func resourceAwsVpcPeeringUpdate(d *schema.ResourceData, meta interface{}) error } func resourceAwsVpcPeeringDelete(d *schema.ResourceData, meta interface{}) error { - ec2conn := meta.(*AWSClient).awsEC2conn + ec2conn := meta.(*AWSClient).ec2conn _, err := ec2conn.DeleteVPCPeeringConnection( &ec2.DeleteVPCPeeringConnectionRequest{ diff --git a/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go b/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go index 307dcb7d9..c374646b8 100644 --- a/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go +++ b/builtin/providers/aws/resource_aws_vpc_peering_connection_test.go @@ -28,7 +28,7 @@ func TestAccAWSVPCPeeringConnection_normal(t *testing.T) { } func testAccCheckAWSVpcPeeringConnectionDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).awsEC2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_vpc_peering_connection" { diff --git a/builtin/providers/aws/resource_aws_vpc_test.go b/builtin/providers/aws/resource_aws_vpc_test.go index b555e0875..092f47806 100644 --- a/builtin/providers/aws/resource_aws_vpc_test.go +++ b/builtin/providers/aws/resource_aws_vpc_test.go @@ -2,11 +2,11 @@ package aws import ( "fmt" - "testing" - + "github.com/hashicorp/aws-sdk-go/aws" + "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - "github.com/mitchellh/goamz/ec2" + "testing" ) func TestAccVpc_basic(t *testing.T) { @@ -119,7 +119,10 @@ func testAccCheckVpcDestroy(s *terraform.State) error { } // Try to find the VPC - resp, err := conn.DescribeVpcs([]string{rs.Primary.ID}, ec2.NewFilter()) + DescribeVpcOpts := &ec2.DescribeVPCsRequest{ + VPCIDs: []string{rs.Primary.ID}, + } + resp, err := conn.DescribeVPCs(DescribeVpcOpts) if err == nil { if len(resp.VPCs) > 0 { return fmt.Errorf("VPCs still exist.") @@ -129,7 +132,7 @@ func testAccCheckVpcDestroy(s *terraform.State) error { } // Verify the error is what we want - ec2err, ok := err.(*ec2.Error) + ec2err, ok := err.(*aws.APIError) if !ok { return err } @@ -143,8 +146,9 @@ func testAccCheckVpcDestroy(s *terraform.State) error { func testAccCheckVpcCidr(vpc *ec2.VPC, expected string) resource.TestCheckFunc { return func(s *terraform.State) error { - if vpc.CidrBlock != expected { - return fmt.Errorf("Bad cidr: %s", vpc.CidrBlock) + CIDRBlock := vpc.CIDRBlock + if *CIDRBlock != expected { + return fmt.Errorf("Bad cidr: %s", *vpc.CIDRBlock) } return nil @@ -163,7 +167,10 @@ func testAccCheckVpcExists(n string, vpc *ec2.VPC) resource.TestCheckFunc { } conn := testAccProvider.Meta().(*AWSClient).ec2conn - resp, err := conn.DescribeVpcs([]string{rs.Primary.ID}, ec2.NewFilter()) + DescribeVpcOpts := &ec2.DescribeVPCsRequest{ + VPCIDs: []string{rs.Primary.ID}, + } + resp, err := conn.DescribeVPCs(DescribeVpcOpts) if err != nil { return err } diff --git a/builtin/providers/aws/structure.go b/builtin/providers/aws/structure.go index 910f748e6..3880f3e82 100644 --- a/builtin/providers/aws/structure.go +++ b/builtin/providers/aws/structure.go @@ -4,11 +4,10 @@ import ( "strings" "github.com/hashicorp/aws-sdk-go/aws" - awsEC2 "github.com/hashicorp/aws-sdk-go/gen/ec2" + "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/aws-sdk-go/gen/elb" "github.com/hashicorp/aws-sdk-go/gen/rds" "github.com/hashicorp/terraform/helper/schema" - "github.com/mitchellh/goamz/ec2" ) // Takes the result of flatmap.Expand for an array of listeners and @@ -17,7 +16,7 @@ func expandListeners(configured []interface{}) ([]elb.Listener, error) { listeners := make([]elb.Listener, 0, len(configured)) // Loop over our configured listeners and create - // an array of goamz compatabile objects + // an array of aws-sdk-go compatabile objects for _, lRaw := range configured { data := lRaw.(map[string]interface{}) @@ -40,10 +39,13 @@ func expandListeners(configured []interface{}) ([]elb.Listener, error) { // Takes the result of flatmap.Expand for an array of ingress/egress // security group rules and returns EC2 API compatible objects -func expandIPPerms(id string, configured []interface{}) []awsEC2.IPPermission { - perms := make([]awsEC2.IPPermission, len(configured)) +func expandIPPerms( + group ec2.SecurityGroup, configured []interface{}) []ec2.IPPermission { + vpc := group.VPCID != nil + + perms := make([]ec2.IPPermission, len(configured)) for i, mRaw := range configured { - var perm awsEC2.IPPermission + var perm ec2.IPPermission m := mRaw.(map[string]interface{}) perm.FromPort = aws.Integer(m["from_port"].(int)) @@ -58,29 +60,38 @@ func expandIPPerms(id string, configured []interface{}) []awsEC2.IPPermission { } } if v, ok := m["self"]; ok && v.(bool) { - groups = append(groups, id) + if vpc { + groups = append(groups, *group.GroupID) + } else { + groups = append(groups, *group.GroupName) + } } if len(groups) > 0 { - perm.UserIDGroupPairs = make([]awsEC2.UserIDGroupPair, len(groups)) + perm.UserIDGroupPairs = make([]ec2.UserIDGroupPair, len(groups)) for i, name := range groups { ownerId, id := "", name if items := strings.Split(id, "/"); len(items) > 1 { ownerId, id = items[0], items[1] } - perm.UserIDGroupPairs[i] = awsEC2.UserIDGroupPair{ + perm.UserIDGroupPairs[i] = ec2.UserIDGroupPair{ GroupID: aws.String(id), UserID: aws.String(ownerId), } + if !vpc { + perm.UserIDGroupPairs[i].GroupID = nil + perm.UserIDGroupPairs[i].GroupName = aws.String(id) + perm.UserIDGroupPairs[i].UserID = nil + } } } if raw, ok := m["cidr_blocks"]; ok { list := raw.([]interface{}) - perm.IPRanges = make([]awsEC2.IPRange, len(list)) + perm.IPRanges = make([]ec2.IPRange, len(list)) for i, v := range list { - perm.IPRanges[i] = awsEC2.IPRange{aws.String(v.(string))} + perm.IPRanges[i] = ec2.IPRange{aws.String(v.(string))} } } @@ -96,7 +107,7 @@ func expandParameters(configured []interface{}) ([]rds.Parameter, error) { parameters := make([]rds.Parameter, 0, len(configured)) // Loop over our configured parameters and create - // an array of goamz compatabile objects + // an array of aws-sdk-go compatabile objects for _, pRaw := range configured { data := pRaw.(map[string]interface{}) @@ -130,16 +141,7 @@ func flattenHealthCheck(check *elb.HealthCheck) []map[string]interface{} { } // Flattens an array of UserSecurityGroups into a []string -func flattenSecurityGroups(list []ec2.UserSecurityGroup) []string { - result := make([]string, 0, len(list)) - for _, g := range list { - result = append(result, g.Id) - } - return result -} - -// Flattens an array of UserSecurityGroups into a []string -func flattenSecurityGroupsSDK(list []awsEC2.UserIDGroupPair) []string { +func flattenSecurityGroups(list []ec2.UserIDGroupPair) []string { result := make([]string, 0, len(list)) for _, g := range list { result = append(result, *g.GroupID) diff --git a/builtin/providers/aws/structure_test.go b/builtin/providers/aws/structure_test.go index d5e470341..12af95328 100644 --- a/builtin/providers/aws/structure_test.go +++ b/builtin/providers/aws/structure_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/hashicorp/aws-sdk-go/aws" - awsEC2 "github.com/hashicorp/aws-sdk-go/gen/ec2" + ec2 "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/aws-sdk-go/gen/elb" "github.com/hashicorp/aws-sdk-go/gen/rds" "github.com/hashicorp/terraform/flatmap" @@ -59,30 +59,34 @@ func TestExpandIPPerms(t *testing.T) { "self": true, }, } - perms := expandIPPerms("foo", expanded) + group := ec2.SecurityGroup{ + GroupID: aws.String("foo"), + VPCID: aws.String("bar"), + } + perms := expandIPPerms(group, expanded) - expected := []awsEC2.IPPermission{ - awsEC2.IPPermission{ + expected := []ec2.IPPermission{ + ec2.IPPermission{ IPProtocol: aws.String("icmp"), FromPort: aws.Integer(1), ToPort: aws.Integer(-1), - IPRanges: []awsEC2.IPRange{awsEC2.IPRange{aws.String("0.0.0.0/0")}}, - UserIDGroupPairs: []awsEC2.UserIDGroupPair{ - awsEC2.UserIDGroupPair{ + IPRanges: []ec2.IPRange{ec2.IPRange{aws.String("0.0.0.0/0")}}, + UserIDGroupPairs: []ec2.UserIDGroupPair{ + ec2.UserIDGroupPair{ UserID: aws.String("foo"), GroupID: aws.String("sg-22222"), }, - awsEC2.UserIDGroupPair{ + ec2.UserIDGroupPair{ GroupID: aws.String("sg-22222"), }, }, }, - awsEC2.IPPermission{ + ec2.IPPermission{ IPProtocol: aws.String("icmp"), FromPort: aws.Integer(1), ToPort: aws.Integer(-1), - UserIDGroupPairs: []awsEC2.UserIDGroupPair{ - awsEC2.UserIDGroupPair{ + UserIDGroupPairs: []ec2.UserIDGroupPair{ + ec2.UserIDGroupPair{ UserID: aws.String("foo"), }, }, @@ -115,6 +119,79 @@ func TestExpandIPPerms(t *testing.T) { } +func TestExpandIPPerms_nonVPC(t *testing.T) { + hash := func(v interface{}) int { + return hashcode.String(v.(string)) + } + + expanded := []interface{}{ + map[string]interface{}{ + "protocol": "icmp", + "from_port": 1, + "to_port": -1, + "cidr_blocks": []interface{}{"0.0.0.0/0"}, + "security_groups": schema.NewSet(hash, []interface{}{ + "sg-11111", + "foo/sg-22222", + }), + }, + map[string]interface{}{ + "protocol": "icmp", + "from_port": 1, + "to_port": -1, + "self": true, + }, + } + group := ec2.SecurityGroup{ + GroupName: aws.String("foo"), + } + perms := expandIPPerms(group, expanded) + + expected := []ec2.IPPermission{ + ec2.IPPermission{ + IPProtocol: aws.String("icmp"), + FromPort: aws.Integer(1), + ToPort: aws.Integer(-1), + IPRanges: []ec2.IPRange{ec2.IPRange{aws.String("0.0.0.0/0")}}, + UserIDGroupPairs: []ec2.UserIDGroupPair{ + ec2.UserIDGroupPair{ + GroupName: aws.String("sg-22222"), + }, + ec2.UserIDGroupPair{ + GroupName: aws.String("sg-22222"), + }, + }, + }, + ec2.IPPermission{ + IPProtocol: aws.String("icmp"), + FromPort: aws.Integer(1), + ToPort: aws.Integer(-1), + UserIDGroupPairs: []ec2.UserIDGroupPair{ + ec2.UserIDGroupPair{ + GroupName: aws.String("foo"), + }, + }, + }, + } + + exp := expected[0] + perm := perms[0] + + if *exp.FromPort != *perm.FromPort { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.FromPort, + *exp.FromPort) + } + + if *exp.IPRanges[0].CIDRIP != *perm.IPRanges[0].CIDRIP { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + *perm.IPRanges[0].CIDRIP, + *exp.IPRanges[0].CIDRIP) + } +} + func TestExpandListeners(t *testing.T) { expanded := []interface{}{ map[string]interface{}{ diff --git a/builtin/providers/aws/tags.go b/builtin/providers/aws/tags.go index b45875c59..1c64b18b4 100644 --- a/builtin/providers/aws/tags.go +++ b/builtin/providers/aws/tags.go @@ -3,11 +3,13 @@ package aws import ( "log" + "github.com/hashicorp/aws-sdk-go/aws" + "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/terraform/helper/schema" - "github.com/mitchellh/goamz/ec2" ) // tagsSchema returns the schema to use for tags. +// func tagsSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeMap, @@ -27,13 +29,21 @@ func setTags(conn *ec2.EC2, d *schema.ResourceData) error { // Set tags if len(remove) > 0 { log.Printf("[DEBUG] Removing tags: %#v", remove) - if _, err := conn.DeleteTags([]string{d.Id()}, remove); err != nil { + err := conn.DeleteTags(&ec2.DeleteTagsRequest{ + Resources: []string{d.Id()}, + Tags: remove, + }) + if err != nil { return err } } if len(create) > 0 { log.Printf("[DEBUG] Creating tags: %#v", create) - if _, err := conn.CreateTags([]string{d.Id()}, create); err != nil { + err := conn.CreateTags(&ec2.CreateTagsRequest{ + Resources: []string{d.Id()}, + Tags: create, + }) + if err != nil { return err } } @@ -49,14 +59,14 @@ func diffTags(oldTags, newTags []ec2.Tag) ([]ec2.Tag, []ec2.Tag) { // First, we're creating everything we have create := make(map[string]interface{}) for _, t := range newTags { - create[t.Key] = t.Value + create[*t.Key] = *t.Value } // Build the list of what to remove var remove []ec2.Tag for _, t := range oldTags { - old, ok := create[t.Key] - if !ok || old != t.Value { + old, ok := create[*t.Key] + if !ok || old != *t.Value { // Delete it! remove = append(remove, t) } @@ -70,8 +80,8 @@ func tagsFromMap(m map[string]interface{}) []ec2.Tag { result := make([]ec2.Tag, 0, len(m)) for k, v := range m { result = append(result, ec2.Tag{ - Key: k, - Value: v.(string), + Key: aws.String(k), + Value: aws.String(v.(string)), }) } @@ -82,7 +92,7 @@ func tagsFromMap(m map[string]interface{}) []ec2.Tag { func tagsToMap(ts []ec2.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[t.Key] = t.Value + result[*t.Key] = *t.Value } return result diff --git a/builtin/providers/aws/tags_sdk.go b/builtin/providers/aws/tags_sdk.go deleted file mode 100644 index 7e9690b78..000000000 --- a/builtin/providers/aws/tags_sdk.go +++ /dev/null @@ -1,106 +0,0 @@ -package aws - -// TODO: Clint: consolidate tags and tags_sdk -// tags_sdk and tags_sdk_test are used only for transition to aws-sdk-go -// and will replace tags and tags_test when the transition to aws-sdk-go/ec2 is -// complete - -import ( - "log" - - "github.com/hashicorp/aws-sdk-go/aws" - "github.com/hashicorp/aws-sdk-go/gen/ec2" - "github.com/hashicorp/terraform/helper/schema" -) - -// tagsSchema returns the schema to use for tags. -// -// TODO: uncomment this when we replace the original tags.go -// -// func tagsSchema() *schema.Schema { -// return &schema.Schema{ -// Type: schema.TypeMap, -// Optional: true, -// } -// } - -// setTags is a helper to set the tags for a resource. It expects the -// tags field to be named "tags" -func setTagsSDK(conn *ec2.EC2, d *schema.ResourceData) error { - if d.HasChange("tags") { - oraw, nraw := d.GetChange("tags") - o := oraw.(map[string]interface{}) - n := nraw.(map[string]interface{}) - create, remove := diffTagsSDK(tagsFromMapSDK(o), tagsFromMapSDK(n)) - - // Set tags - if len(remove) > 0 { - log.Printf("[DEBUG] Removing tags: %#v", remove) - err := conn.DeleteTags(&ec2.DeleteTagsRequest{ - Resources: []string{d.Id()}, - Tags: remove, - }) - if err != nil { - return err - } - } - if len(create) > 0 { - log.Printf("[DEBUG] Creating tags: %#v", create) - err := conn.CreateTags(&ec2.CreateTagsRequest{ - Resources: []string{d.Id()}, - Tags: create, - }) - if err != nil { - return err - } - } - } - - return nil -} - -// diffTags takes our tags locally and the ones remotely and returns -// the set of tags that must be created, and the set of tags that must -// be destroyed. -func diffTagsSDK(oldTags, newTags []ec2.Tag) ([]ec2.Tag, []ec2.Tag) { - // First, we're creating everything we have - create := make(map[string]interface{}) - for _, t := range newTags { - create[*t.Key] = *t.Value - } - - // Build the list of what to remove - var remove []ec2.Tag - for _, t := range oldTags { - old, ok := create[*t.Key] - if !ok || old != *t.Value { - // Delete it! - remove = append(remove, t) - } - } - - return tagsFromMapSDK(create), remove -} - -// tagsFromMap returns the tags for the given map of data. -func tagsFromMapSDK(m map[string]interface{}) []ec2.Tag { - result := make([]ec2.Tag, 0, len(m)) - for k, v := range m { - result = append(result, ec2.Tag{ - Key: aws.String(k), - Value: aws.String(v.(string)), - }) - } - - return result -} - -// tagsToMap turns the list of tags into a map. -func tagsToMapSDK(ts []ec2.Tag) map[string]string { - result := make(map[string]string) - for _, t := range ts { - result[*t.Key] = *t.Value - } - - return result -} diff --git a/builtin/providers/aws/tags_sdk_test.go b/builtin/providers/aws/tags_sdk_test.go deleted file mode 100644 index 5a5b0e600..000000000 --- a/builtin/providers/aws/tags_sdk_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package aws - -import ( - "fmt" - "reflect" - "testing" - - "github.com/hashicorp/aws-sdk-go/gen/ec2" - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" -) - -func TestDiffTagsSDK(t *testing.T) { - cases := []struct { - Old, New map[string]interface{} - Create, Remove map[string]string - }{ - // Basic add/remove - { - Old: map[string]interface{}{ - "foo": "bar", - }, - New: map[string]interface{}{ - "bar": "baz", - }, - Create: map[string]string{ - "bar": "baz", - }, - Remove: map[string]string{ - "foo": "bar", - }, - }, - - // Modify - { - Old: map[string]interface{}{ - "foo": "bar", - }, - New: map[string]interface{}{ - "foo": "baz", - }, - Create: map[string]string{ - "foo": "baz", - }, - Remove: map[string]string{ - "foo": "bar", - }, - }, - } - - for i, tc := range cases { - c, r := diffTagsSDK(tagsFromMapSDK(tc.Old), tagsFromMapSDK(tc.New)) - cm := tagsToMapSDK(c) - rm := tagsToMapSDK(r) - if !reflect.DeepEqual(cm, tc.Create) { - t.Fatalf("%d: bad create: %#v", i, cm) - } - if !reflect.DeepEqual(rm, tc.Remove) { - t.Fatalf("%d: bad remove: %#v", i, rm) - } - } -} - -// testAccCheckTags can be used to check the tags on a resource. -func testAccCheckTagsSDK( - ts *[]ec2.Tag, key string, value string) resource.TestCheckFunc { - return func(s *terraform.State) error { - m := tagsToMapSDK(*ts) - v, ok := m[key] - if value != "" && !ok { - return fmt.Errorf("Missing tag: %s", key) - } else if value == "" && ok { - return fmt.Errorf("Extra tag: %s", key) - } - if value == "" { - return nil - } - - if v != value { - return fmt.Errorf("%s: bad value: %s", key, v) - } - - return nil - } -} diff --git a/builtin/providers/aws/tags_test.go b/builtin/providers/aws/tags_test.go index 6e89492ca..16578ac1b 100644 --- a/builtin/providers/aws/tags_test.go +++ b/builtin/providers/aws/tags_test.go @@ -5,9 +5,9 @@ import ( "reflect" "testing" + "github.com/hashicorp/aws-sdk-go/gen/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" - "github.com/mitchellh/goamz/ec2" ) func TestDiffTags(t *testing.T) { diff --git a/state/remote/consul.go b/state/remote/consul.go index 274b5e37d..791f4dca3 100644 --- a/state/remote/consul.go +++ b/state/remote/consul.go @@ -20,6 +20,9 @@ func consulFactory(conf map[string]string) (Client, error) { if addr, ok := conf["address"]; ok && addr != "" { config.Address = addr } + if scheme, ok := conf["scheme"]; ok && scheme != "" { + config.Scheme = scheme + } client, err := consulapi.NewClient(config) if err != nil { diff --git a/website/source/docs/commands/remote.html.markdown b/website/source/docs/commands/remote.html.markdown index 3bc96c802..22d341891 100644 --- a/website/source/docs/commands/remote.html.markdown +++ b/website/source/docs/commands/remote.html.markdown @@ -16,7 +16,7 @@ Terraform will automatically fetch the latest state from the remote server when necessary and if any updates are made, the newest state is persisted back to the remote server. In this mode, users do not need to durably store the state using version -control or shared storaged. +control or shared storage. ## Usage diff --git a/website/source/docs/providers/aws/r/internet_gateway.html.markdown b/website/source/docs/providers/aws/r/internet_gateway.html.markdown index ec79f922a..cefedc6ad 100644 --- a/website/source/docs/providers/aws/r/internet_gateway.html.markdown +++ b/website/source/docs/providers/aws/r/internet_gateway.html.markdown @@ -29,6 +29,18 @@ The following arguments are supported: * `vpc_id` - (Required) The VPC ID to create in. * `tags` - (Optional) A mapping of tags to assign to the resource. +-> **Note:** It's recommended to denote that the AWS Instance or Elastic IP depends on the Internet Gateway. For example: + + + resource "aws_internet_gateway" "gw" { + vpc_id = "${aws_vpc.main.id}" + } + + resource "aws_instance" "foo" { + depends_on = ["aws_internet_gateway.gw"] + } + + ## Attributes Reference The following attributes are exported: diff --git a/website/source/docs/providers/aws/r/security_group.html.markdown b/website/source/docs/providers/aws/r/security_group.html.markdown index 869f4bdc5..f23bbcf16 100644 --- a/website/source/docs/providers/aws/r/security_group.html.markdown +++ b/website/source/docs/providers/aws/r/security_group.html.markdown @@ -17,7 +17,7 @@ Basic usage ``` resource "aws_security_group" "allow_all" { name = "allow_all" - description = "Allow all inbound traffic" + description = "Allow all inbound traffic" ingress { from_port = 0 diff --git a/website/source/docs/providers/aws/r/vpc_peering.html.markdown b/website/source/docs/providers/aws/r/vpc_peering.html.markdown index 59af3c0ca..1d396a584 100644 --- a/website/source/docs/providers/aws/r/vpc_peering.html.markdown +++ b/website/source/docs/providers/aws/r/vpc_peering.html.markdown @@ -56,4 +56,4 @@ The following attributes are exported: ## Notes -You still have to accept the peering with the aws console, aws-cli or goamz +You still have to accept the peering with the aws console, aws-cli or aws-sdk-go.