Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/eip, d/eip: add extra computed attributes and BYOIP feature support #6518

Merged
merged 4 commits into from
Nov 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions aws/data_source_aws_eip.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,45 @@ func dataSourceAwsEip() *schema.Resource {
Read: dataSourceAwsEipRead,

Schema: map[string]*schema.Schema{
"association_id": {
Type: schema.TypeString,
Computed: true,
},
"domain": {
Type: schema.TypeString,
Computed: true,
},
"filter": ec2CustomFiltersSchema(),
"id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"instance_id": {
Type: schema.TypeString,
Computed: true,
},
"network_interface_id": {
Type: schema.TypeString,
Computed: true,
},
"network_interface_owner_id": {
Type: schema.TypeString,
Computed: true,
},
"private_ip": {
Type: schema.TypeString,
Computed: true,
},
"public_ip": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"public_ipv4_pool": {
Type: schema.TypeString,
Computed: true,
},
"tags": tagsSchemaComputed(),
},
}
Expand Down Expand Up @@ -79,7 +107,14 @@ func dataSourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
d.SetId(aws.StringValue(eip.PublicIp))
}

d.Set("association_id", eip.AssociationId)
d.Set("domain", eip.Domain)
d.Set("instance_id", eip.InstanceId)
d.Set("network_interface_id", eip.NetworkInterfaceId)
d.Set("network_interface_owner_id", eip.NetworkInterfaceOwnerId)
d.Set("private_ip", eip.PrivateIpAddress)
d.Set("public_ip", eip.PublicIp)
d.Set("public_ipv4_pool", eip.PublicIpv4Pool)
d.Set("tags", tagsToMap(eip.Tags))

return nil
Expand Down
115 changes: 115 additions & 0 deletions aws/data_source_aws_eip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func TestAccDataSourceAwsEip_PublicIP_VPC(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"),
resource.TestCheckResourceAttrPair(dataSourceName, "public_ip", resourceName, "public_ip"),
resource.TestCheckResourceAttrPair(dataSourceName, "domain", resourceName, "domain"),
),
},
},
Expand All @@ -107,6 +108,47 @@ func TestAccDataSourceAwsEip_Tags(t *testing.T) {
})
}

func TestAccDataSourceAwsEip_NetworkInterface(t *testing.T) {
dataSourceName := "data.aws_eip.test"
resourceName := "aws_eip.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAwsEipConfigNetworkInterface,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"),
resource.TestCheckResourceAttrPair(dataSourceName, "network_interface_id", resourceName, "network_interface"),
resource.TestCheckResourceAttrPair(dataSourceName, "private_ip", resourceName, "private_ip"),
resource.TestCheckResourceAttrPair(dataSourceName, "domain", resourceName, "domain"),
),
},
},
})
}

func TestAccDataSourceAwsEip_Instance(t *testing.T) {
dataSourceName := "data.aws_eip.test"
resourceName := "aws_eip.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAwsEipConfigInstance,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"),
resource.TestCheckResourceAttrPair(dataSourceName, "instance_id", resourceName, "instance"),
resource.TestCheckResourceAttrPair(dataSourceName, "association_id", resourceName, "association_id"),
),
},
},
})
}

func testAccDataSourceAwsEipConfigFilter(rName string) string {
return fmt.Sprintf(`
resource "aws_eip" "test" {
Expand Down Expand Up @@ -175,3 +217,76 @@ data "aws_eip" "test" {
}
`, rName)
}

const testAccDataSourceAwsEipConfigNetworkInterface = `
resource "aws_vpc" "test" {
cidr_block = "10.1.0.0/16"
}

resource "aws_subnet" "test" {
vpc_id = "${aws_vpc.test.id}"
cidr_block = "10.1.0.0/24"
}

resource "aws_internet_gateway" "test" {
vpc_id = "${aws_vpc.test.id}"
}

resource "aws_network_interface" "test" {
subnet_id = "${aws_subnet.test.id}"
}

resource "aws_eip" "test" {
vpc = true
network_interface = "${aws_network_interface.test.id}"
}

data "aws_eip" "test" {
filter {
name = "network-interface-id"
values = ["${aws_eip.test.network_interface}"]
}
}
`

const testAccDataSourceAwsEipConfigInstance = `
resource "aws_vpc" "test" {
cidr_block = "10.2.0.0/16"
}

resource "aws_subnet" "test" {
vpc_id = "${aws_vpc.test.id}"
cidr_block = "10.2.0.0/24"
}

resource "aws_internet_gateway" "test" {
vpc_id = "${aws_vpc.test.id}"
}

data "aws_ami" "test" {
most_recent = true
name_regex = "^amzn-ami.*ecs-optimized$"

owners = [
"amazon",
]
}

resource "aws_instance" "test" {
ami = "${data.aws_ami.test.id}"
subnet_id = "${aws_subnet.test.id}"
instance_type = "t2.micro"
}

resource "aws_eip" "test" {
vpc = true
instance = "${aws_instance.test.id}"
}

data "aws_eip" "test" {
filter {
name = "instance-id"
values = ["${aws_eip.test.instance}"]
}
}
`
12 changes: 12 additions & 0 deletions aws/resource_aws_eip.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ func resourceAwsEip() *schema.Resource {
Optional: true,
},

"public_ipv4_pool": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
bflad marked this conversation as resolved.
Show resolved Hide resolved
},

"tags": tagsSchema(),
},
}
Expand All @@ -98,6 +105,10 @@ func resourceAwsEipCreate(d *schema.ResourceData, meta interface{}) error {
Domain: aws.String(domainOpt),
}

if v, ok := d.GetOk("public_ipv4_pool"); ok {
allocOpts.PublicIpv4Pool = aws.String(v.(string))
}

log.Printf("[DEBUG] EIP create configuration: %#v", allocOpts)
allocResp, err := ec2conn.AllocateAddress(allocOpts)
if err != nil {
Expand Down Expand Up @@ -211,6 +222,7 @@ func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
}
d.Set("private_ip", address.PrivateIpAddress)
d.Set("public_ip", address.PublicIp)
d.Set("public_ipv4_pool", address.PublicIpv4Pool)

// On import (domain never set, which it must've been if we created),
// set the 'vpc' attribute depending on if we're in a VPC.
Expand Down
69 changes: 67 additions & 2 deletions aws/resource_aws_eip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,56 @@ func TestAccAWSEIP_tags(t *testing.T) {
})
}

func TestAccAWSEIP_PublicIpv4Pool_default(t *testing.T) {
var conf ec2.Address
resourceName := "aws_eip.bar"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: resourceName,
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEIPDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSEIPConfig_PublicIpv4Pool_default,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEIPExists(resourceName, &conf),
testAccCheckAWSEIPAttributes(&conf),
resource.TestCheckResourceAttr(resourceName, "public_ipv4_pool", "amazon"),
),
},
},
})
}

func TestAccAWSEIP_PublicIpv4Pool_custom(t *testing.T) {
if os.Getenv("AWS_EC2_EIP_PUBLIC_IPV4_POOL") == "" {
t.Skip("Environment variable AWS_EC2_EIP_PUBLIC_IPV4_POOL is not set")
}

var conf ec2.Address
resourceName := "aws_eip.bar"

poolName := fmt.Sprintf("%s", os.Getenv("AWS_EC2_EIP_PUBLIC_IPV4_POOL"))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: resourceName,
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEIPDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSEIPConfig_PublicIpv4Pool_custom(poolName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEIPExists(resourceName, &conf),
testAccCheckAWSEIPAttributes(&conf),
resource.TestCheckResourceAttr(resourceName, "public_ipv4_pool", poolName),
bflad marked this conversation as resolved.
Show resolved Hide resolved
),
},
},
})
}

func testAccCheckAWSEIPDisappears(v *ec2.Address) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn
Expand Down Expand Up @@ -454,6 +504,21 @@ resource "aws_eip" "bar" {
`, rName, testName)
}

const testAccAWSEIPConfig_PublicIpv4Pool_default = `
resource "aws_eip" "bar" {
vpc = true
}
`

func testAccAWSEIPConfig_PublicIpv4Pool_custom(poolName string) string {
return fmt.Sprintf(`
resource "aws_eip" "bar" {
vpc = true
public_ipv4_pool = "%s"
}
`, poolName)
}

const testAccAWSEIPInstanceEc2Classic = `
provider "aws" {
region = "us-east-1"
Expand Down Expand Up @@ -716,7 +781,7 @@ resource "aws_subnet" "bar" {
availability_zone = "us-west-2a"
cidr_block = "10.0.0.0/24"
tags {
Name = "tf-acc-eip-network-interface"
Name = "tf-acc-eip-network-interface"
}
}

Expand Down Expand Up @@ -750,7 +815,7 @@ resource "aws_subnet" "bar" {
availability_zone = "us-west-2a"
cidr_block = "10.0.0.0/24"
tags {
Name = "tf-acc-eip-multi-network-interface"
Name = "tf-acc-eip-multi-network-interface"
}
}

Expand Down
7 changes: 7 additions & 0 deletions website/docs/d/eip.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ Elastic IP whose data will be exported as attributes.

In addition to all arguments above, the following attributes are exported:

* `association_id` - The ID representing the association of the address with an instance in a VPC.
* `domain` - Indicates whether the address is for use in EC2-Classic (standard) or in a VPC (vpc).
* `id` - If VPC Elastic IP, the allocation identifier. If EC2-Classic Elastic IP, the public IP address.
* `instance_id` - The ID of the instance that the address is associated with (if any).
* `network_interface_id` - The ID of the network interface.
* `network_interface_owner_id` - The ID of the AWS account that owns the network interface.
* `private_ip` - The private IP address associated with the Elastic IP address.
* `public_ip` - Public IP address of Elastic IP.
* `public_ipv4_pool` - The ID of an address pool.
* `tags` - Key-value map of tags associated with Elastic IP.
11 changes: 11 additions & 0 deletions website/docs/r/eip.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ resource "aws_eip" "bar" {
}
```

Allocating EIP from the BYOIP pool:

```hcl
resource "aws_eip" "byoip-ip" {
vpc = true
public_ipv4_pool = "ipv4pool-ec2-012345"
}
```

## Argument Reference

The following arguments are supported:
Expand All @@ -95,6 +104,7 @@ The following arguments are supported:
associate with the Elastic IP address. If no private IP address is specified,
the Elastic IP address is associated with the primary private IP address.
* `tags` - (Optional) A mapping of tags to assign to the resource.
* `public_ipv4_pool` - (Optional) EC2 IPv4 address pool identifier or `amazon`. This option is only available for VPC EIPs.

~> **NOTE:** You can specify either the `instance` ID or the `network_interface` ID,
but not both. Including both will **not** return an error from the AWS API, but will
Expand All @@ -112,6 +122,7 @@ In addition to all arguments above, the following attributes are exported:
* `public_ip` - Contains the public IP address.
* `instance` - Contains the ID of the attached instance.
* `network_interface` - Contains the ID of the attached network interface.
* `public_ipv4_pool` - EC2 IPv4 address pool identifier (if in VPC).

## Timeouts
`aws_eip` provides the following [Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
Expand Down