provider/aws: Add aws_eip data source (#9833)

* provider/aws: Add the aws_eip data source

* Document the aws_eip data source on the website

* provider/aws: support query by public_ip for aws_eip data source
This commit is contained in:
Ryan Hoegg 2016-12-13 06:09:21 -06:00 committed by Paul Stack
parent e58bb9d824
commit 73213793ca
4 changed files with 192 additions and 0 deletions

View File

@ -0,0 +1,64 @@
package aws
import (
"fmt"
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourceAwsEip() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsEipRead,
Schema: map[string]*schema.Schema{
"id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"public_ip": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}
func dataSourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn
req := &ec2.DescribeAddressesInput{}
if id := d.Get("id"); id != "" {
req.AllocationIds = []*string{aws.String(id.(string))}
}
if public_ip := d.Get("public_ip"); public_ip != "" {
req.PublicIps = []*string{aws.String(public_ip.(string))}
}
log.Printf("[DEBUG] DescribeAddresses %s\n", req)
resp, err := conn.DescribeAddresses(req)
if err != nil {
return err
}
if resp == nil || len(resp.Addresses) == 0 {
return fmt.Errorf("no matching Elastic IP found")
}
if len(resp.Addresses) > 1 {
return fmt.Errorf("multiple Elastic IPs matched; use additional constraints to reduce matches to a single Elastic IP")
}
eip := resp.Addresses[0]
d.SetId(*eip.AllocationId)
d.Set("id", eip.AllocationId)
d.Set("public_ip", eip.PublicIp)
return nil
}

View File

@ -0,0 +1,77 @@
package aws
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccDataSourceAwsEip(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDataSourceAwsEipConfig,
Check: resource.ComposeTestCheckFunc(
testAccDataSourceAwsEipCheck("data.aws_eip.by_id"),
testAccDataSourceAwsEipCheck("data.aws_eip.by_public_ip"),
),
},
},
})
}
func testAccDataSourceAwsEipCheck(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
if !ok {
return fmt.Errorf("root module has no resource called %s", name)
}
eipRs, ok := s.RootModule().Resources["aws_eip.test"]
if !ok {
return fmt.Errorf("can't find aws_eip.test in state")
}
attr := rs.Primary.Attributes
if attr["id"] != eipRs.Primary.Attributes["id"] {
return fmt.Errorf(
"id is %s; want %s",
attr["id"],
eipRs.Primary.Attributes["id"],
)
}
if attr["public_ip"] != eipRs.Primary.Attributes["public_ip"] {
return fmt.Errorf(
"public_ip is %s; want %s",
attr["public_ip"],
eipRs.Primary.Attributes["public_ip"],
)
}
return nil
}
}
const testAccDataSourceAwsEipConfig = `
provider "aws" {
region = "us-west-2"
}
resource "aws_eip" "wrong1" {}
resource "aws_eip" "test" {}
resource "aws_eip" "wrong2" {}
data "aws_eip" "by_id" {
id = "${aws_eip.test.id}"
}
data "aws_eip" "by_public_ip" {
public_ip = "${aws_eip.test.public_ip}"
}
`

View File

@ -155,6 +155,7 @@ func Provider() terraform.ResourceProvider {
"aws_ebs_snapshot": dataSourceAwsEbsSnapshot(),
"aws_ebs_volume": dataSourceAwsEbsVolume(),
"aws_ecs_container_definition": dataSourceAwsEcsContainerDefinition(),
"aws_eip": dataSourceAwsEip(),
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
"aws_iam_policy_document": dataSourceAwsIamPolicyDocument(),
"aws_iam_server_certificate": dataSourceAwsIAMServerCertificate(),

View File

@ -0,0 +1,50 @@
---
layout: "aws"
page_title: "AWS: aws_eip"
sidebar_current: "docs-aws-datasource-eip"
description: |-
Provides details about a specific Elastic IP
---
# aws\_eip
`aws_eip` provides details about a specific Elastic IP.
This resource can prove useful when a module accepts an allocation ID or
public IP as an input variable and needs to determine the other.
## Example Usage
The following example shows how one might accept a public IP as a variable
and use this data source to obtain the allocation ID.
```
variable "instance_id" {}
variable "public_ip" {}
data "aws_eip" "proxy_ip" {
public_ip = "${var.public_ip}"
}
aws_eip_association "proxy_eip" {
instance_id = "${var.instance_id}"
allocation_id = "${data.aws_eip.proxy_ip.id}"
}
```
## Argument Reference
The arguments of this data source act as filters for querying the available
Elastic IPs in the current region. The given filters must match exactly one
Elastic IP whose data will be exported as attributes.
* `id` - (Optional) The allocation id of the specific EIP to retrieve.
* `public_ip` - (Optional) The public IP of the specific EIP to retrieve.
## Attributes Reference
All of the argument attributes are also exported as result attributes. This
data source will complete the data by populating any fields that are not
included in the configuration with the data for the selected Elastic IP.