diff --git a/builtin/providers/aws/data_source_aws_region.go b/builtin/providers/aws/data_source_aws_region.go new file mode 100644 index 000000000..ed75f7056 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_region.go @@ -0,0 +1,84 @@ +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 dataSourceAwsRegion() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsRegionRead, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "current": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + + "endpoint": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } +} + +func dataSourceAwsRegionRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + currentRegion := meta.(*AWSClient).region + + req := &ec2.DescribeRegionsInput{} + + req.RegionNames = make([]*string, 0, 2) + if name := d.Get("name").(string); name != "" { + req.RegionNames = append(req.RegionNames, aws.String(name)) + } + + if d.Get("current").(bool) { + req.RegionNames = append(req.RegionNames, aws.String(currentRegion)) + } + + req.Filters = buildEC2AttributeFilterList( + map[string]string{ + "endpoint": d.Get("endpoint").(string), + }, + ) + if len(req.Filters) == 0 { + // Don't send an empty filters list; the EC2 API won't accept it. + req.Filters = nil + } + + log.Printf("[DEBUG] DescribeRegions %s\n", req) + resp, err := conn.DescribeRegions(req) + if err != nil { + return err + } + if resp == nil || len(resp.Regions) == 0 { + return fmt.Errorf("no matching regions found") + } + if len(resp.Regions) > 1 { + return fmt.Errorf("multiple regions matched; use additional constraints to reduce matches to a single region") + } + + region := resp.Regions[0] + + d.SetId(*region.RegionName) + d.Set("id", region.RegionName) + d.Set("name", region.RegionName) + d.Set("endpoint", region.Endpoint) + d.Set("current", *region.RegionName == currentRegion) + + return nil +} diff --git a/builtin/providers/aws/data_source_aws_region_test.go b/builtin/providers/aws/data_source_aws_region_test.go new file mode 100644 index 000000000..370c4b2b0 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_region_test.go @@ -0,0 +1,64 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccDataSourceAwsRegion(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourceAwsRegionConfig, + Check: resource.ComposeTestCheckFunc( + testAccDataSourceAwsRegionCheck("data.aws_region.by_name_current", "us-west-2", "true"), + testAccDataSourceAwsRegionCheck("data.aws_region.by_name_other", "us-west-1", "false"), + testAccDataSourceAwsRegionCheck("data.aws_region.by_current", "us-west-2", "true"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsRegionCheck(name, region, current 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) + } + + attr := rs.Primary.Attributes + + if attr["name"] != region { + return fmt.Errorf("bad name %s", attr["name"]) + } + if attr["current"] != current { + return fmt.Errorf("bad current %s; want %s", attr["current"], current) + } + + return nil + } +} + +const testAccDataSourceAwsRegionConfig = ` +provider "aws" { + region = "us-west-2" +} + +data "aws_region" "by_name_current" { + name = "us-west-2" +} + +data "aws_region" "by_name_other" { + name = "us-west-1" +} + +data "aws_region" "by_current" { + current = true +} +` diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index cbecd8b19..e92cd7f59 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -153,6 +153,7 @@ func Provider() terraform.ResourceProvider { "aws_iam_policy_document": dataSourceAwsIamPolicyDocument(), "aws_ip_ranges": dataSourceAwsIPRanges(), "aws_redshift_service_account": dataSourceAwsRedshiftServiceAccount(), + "aws_region": dataSourceAwsRegion(), "aws_s3_bucket_object": dataSourceAwsS3BucketObject(), "aws_subnet": dataSourceAwsSubnet(), "aws_vpc": dataSourceAwsVpc(), diff --git a/website/source/docs/providers/aws/d/region.html.markdown b/website/source/docs/providers/aws/d/region.html.markdown new file mode 100644 index 000000000..4105639c0 --- /dev/null +++ b/website/source/docs/providers/aws/d/region.html.markdown @@ -0,0 +1,54 @@ +--- +layout: "aws" +page_title: "AWS: aws_region" +sidebar_current: "docs-aws-datasource-region" +description: |- + Provides details about a specific service region +--- + +# aws\_region + +`aws_region` provides details about a specific AWS region. + +As well as validating a given region name (and optionally obtaining its +endpoint) this resource can be used to discover the name of the region +configured within the provider. The latter can be useful in a child module +which is inheriting an AWS provider configuration from its parent module. + +## Example Usage + +The following example shows how the resource might be used to obtain +the name of the AWS region configured on the provider. + +``` +data "aws_region" "current" { + current = true +} +``` + +## Argument Reference + +The arguments of this data source act as filters for querying the available +regions. The given filters must match exactly one region whose data will be +exported as attributes. + +* `name` - (Optional) The full name of the region to select. + +* `current` - (Optional) Set to `true` to match only the region configured + in the provider. (It is not meaningful to set this to `false`.) + +* `endpoint` - (Optional) The endpoint of the region to select. + +At least one of the above attributes should be provided to ensure that only +one region is matched. + +## Attributes Reference + +The following attributes are exported: + +* `name` - The name of the selected region. + +* `current` - `true` if the selected region is the one configured on the + provider, or `false` otherwise. + +* `endpoint` - The endpoint for the selected region. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index 8590c1ee8..2138cb470 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -41,9 +41,12 @@ > aws_ip_ranges - > - aws_redshift_service_account - + > + aws_redshift_service_account + + > + aws_region + > aws_s3_bucket_object