provider/aws: Adding IPv6 address to instance causes perpetual diff

Fixes: #14032

When you are using an IPv6 address directly to an instance, it was
causing the ipv6_address_count to try and ForceNew resource. It wasn't
marked as computed

I was able to see this here:

```
-/+ aws_instance.test
    ami:                          "ami-c5eabbf5" => "ami-c5eabbf5"
    associate_public_ip_address:  "false" => "<computed>"
    availability_zone:            "us-west-2a" => "<computed>"
    ebs_block_device.#:           "0" => "<computed>"
    ephemeral_block_device.#:     "0" => "<computed>"
    instance_state:               "running" => "<computed>"
    instance_type:                "t2.micro" => "t2.micro"
    ipv6_address_count:           "1" => "0" (forces new resource)
    ipv6_addresses.#:             "1" => "1"
    ipv6_addresses.0:             "2600:1f14:bb2:e501::10" => "2600:1f14:bb2:e501::10"
    key_name:                     "" => "<computed>"
    network_interface.#:          "0" => "<computed>"
    network_interface_id:         "eni-d19115ec" => "<computed>"
    placement_group:              "" => "<computed>"
    primary_network_interface_id: "eni-d19115ec" => "<computed>"
    private_dns:                  "ip-10-20-1-252.us-west-2.compute.internal" => "<computed>"
    private_ip:                   "10.20.1.252" => "<computed>"
    public_dns:                   "" => "<computed>"
    public_ip:                    "" => "<computed>"
    root_block_device.#:          "1" => "<computed>"
    security_groups.#:            "0" => "<computed>"
    source_dest_check:            "true" => "true"
    subnet_id:                    "subnet-3fdfb476" => "subnet-3fdfb476"
    tags.%:                       "1" => "1"
    tags.Name:                    "stack72" => "stack72"
    tenancy:                      "default" => "<computed>"
    volume_tags.%:                "0" => "<computed>"
    vpc_security_group_ids.#:     "1" => "<computed>"
```

It now works as expected:

```
% terraform plan                                                                                 ✹ ✭
[WARN] /Users/stacko/Code/go/bin/terraform-provider-aws overrides an internal plugin for aws-provider.
  If you did not expect to see this message you will need to remove the old plugin.
  See https://www.terraform.io/docs/internals/internal-plugins.html
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

aws_vpc.foo: Refreshing state... (ID: vpc-fa61669d)
aws_subnet.foo: Refreshing state... (ID: subnet-3fdfb476)
aws_internet_gateway.foo: Refreshing state... (ID: igw-70629a17)
aws_route_table.test: Refreshing state... (ID: rtb-0a52e16c)
aws_instance.test: Refreshing state... (ID: i-0971755345296aca5)
aws_route_table_association.a: Refreshing state... (ID: rtbassoc-b12493c8)
No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, Terraform
doesn't need to do anything.
```
This commit is contained in:
stack72 2017-05-10 17:20:48 +03:00 committed by Paul Stack
parent 966e4d275f
commit db432ad765
2 changed files with 60 additions and 6 deletions

View File

@ -217,6 +217,7 @@ func resourceAwsInstance() *schema.Resource {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Computed: true,
},
"ipv6_addresses": {
@ -227,7 +228,6 @@ func resourceAwsInstance() *schema.Resource {
Elem: &schema.Schema{
Type: schema.TypeString,
},
ConflictsWith: []string{"ipv6_address_count"},
},
"tenancy": {
@ -420,13 +420,20 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error {
UserData: instanceOpts.UserData64,
}
if v, ok := d.GetOk("ipv6_address_count"); ok {
runOpts.Ipv6AddressCount = aws.Int64(int64(v.(int)))
ipv6Count, ipv6CountOk := d.GetOk("ipv6_address_count")
ipv6Address, ipv6AddressOk := d.GetOk("ipv6_addresses")
if ipv6AddressOk && ipv6CountOk {
return fmt.Errorf("Only 1 of `ipv6_address_count` or `ipv6_addresses` can be specified")
}
if v, ok := d.GetOk("ipv6_addresses"); ok {
ipv6Addresses := make([]*ec2.InstanceIpv6Address, len(v.([]interface{})))
for _, address := range v.([]interface{}) {
if ipv6CountOk {
runOpts.Ipv6AddressCount = aws.Int64(int64(ipv6Count.(int)))
}
if ipv6AddressOk {
ipv6Addresses := make([]*ec2.InstanceIpv6Address, len(ipv6Address.([]interface{})))
for _, address := range ipv6Address.([]interface{}) {
ipv6Address := &ec2.InstanceIpv6Address{
Ipv6Address: aws.String(address.(string)),
}

View File

@ -3,6 +3,7 @@ package aws
import (
"fmt"
"reflect"
"regexp"
"testing"
"github.com/aws/aws-sdk-go/aws"
@ -522,6 +523,21 @@ func TestAccAWSInstance_ipv6_supportAddressCount(t *testing.T) {
})
}
func TestAccAWSInstance_ipv6AddressCountAndSingleAddressCausesError(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceConfigIpv6ErrorConfig,
ExpectError: regexp.MustCompile("Only 1 of `ipv6_address_count` or `ipv6_addresses` can be specified"),
},
},
})
}
func TestAccAWSInstance_multipleRegions(t *testing.T) {
var v ec2.Instance
@ -1355,6 +1371,37 @@ resource "aws_instance" "foo" {
}
`
const testAccInstanceConfigIpv6ErrorConfig = `
resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16"
assign_generated_ipv6_cidr_block = true
tags {
Name = "tf-ipv6-instance-acc-test"
}
}
resource "aws_subnet" "foo" {
cidr_block = "10.1.1.0/24"
vpc_id = "${aws_vpc.foo.id}"
ipv6_cidr_block = "${cidrsubnet(aws_vpc.foo.ipv6_cidr_block, 8, 1)}"
tags {
Name = "tf-ipv6-instance-acc-test"
}
}
resource "aws_instance" "foo" {
# us-west-2
ami = "ami-c5eabbf5"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.foo.id}"
ipv6_addresses = ["2600:1f14:bb2:e501::10"]
ipv6_address_count = 1
tags {
Name = "tf-ipv6-instance-acc-test"
}
}
`
const testAccInstanceConfigIpv6Support = `
resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16"