Skip to content

Commit

Permalink
New resource - aws_availability_zones
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Marchesi committed Apr 18, 2016
1 parent c280d62 commit 4fb27ff
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 0 deletions.
1 change: 1 addition & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func Provider() terraform.ResourceProvider {
"aws_autoscaling_notification": resourceAwsAutoscalingNotification(),
"aws_autoscaling_policy": resourceAwsAutoscalingPolicy(),
"aws_autoscaling_schedule": resourceAwsAutoscalingSchedule(),
"aws_availability_zones": resourceAwsAvailabilityZones(),
"aws_cloudformation_stack": resourceAwsCloudFormationStack(),
"aws_cloudfront_distribution": resourceAwsCloudFrontDistribution(),
"aws_cloudfront_origin_access_identity": resourceAwsCloudFrontOriginAccessIdentity(),
Expand Down
134 changes: 134 additions & 0 deletions builtin/providers/aws/resource_aws_availability_zones.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package aws

import (
"fmt"
"sort"

"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

// AWS availability zones resource - get the availability zones available to
// your account/connection.
//
// Example:
//
// resource "aws_availability_zones" "availability_zones" {
// filter {
// name = "state"
// values = "available"
// }
// zone_names = ["us-east-1a"]
// }
//
// Parameters:
//
// filter (Optional): One or more name/value pairs to filter off of.
// For a full reference, check out
// http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-availability-zones.html.
//
// zone_names (Optional): A list of availability zones to directly filter for.
//
//
// Attributes Reference:
//
// Id - A unique ID generated by Terraform.
// availability_zones - The list or returned availability zones.
//

func resourceAwsAvailabilityZones() *schema.Resource {
return &schema.Resource{
Create: resourceAwsAvailabilityZonesRead,
Read: resourceAwsAvailabilityZonesRead,
Delete: resourceAwsAvailabilityZonesDelete,

Schema: map[string]*schema.Schema{
"zone_names": &schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"filter": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},

"values": &schema.Schema{
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
"availability_zones": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

// Delete the "Resource".
func resourceAwsAvailabilityZonesDelete(d *schema.ResourceData, meta interface{}) error {
d.SetId("")
return nil
}

// Perform the AZ lookups.
func resourceAwsAvailabilityZonesRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

filters, filtersOk := d.GetOk("filter")
zones, zonesOk := d.GetOk("zone_names")

params := &ec2.DescribeAvailabilityZonesInput{}
if filtersOk {
params.Filters = buildEc2Filters(filters.(*schema.Set))
}
if zonesOk {
params.ZoneNames = expandStringList(zones.([]interface{}))
}

resp, err := conn.DescribeAvailabilityZones(params)
if err != nil {
return err
}
if len(resp.AvailabilityZones) < 1 {
return fmt.Errorf("Your query returned no results. Please change your filters and try again.")
}
return azDescriptionAttributes(d, resp.AvailabilityZones)
}

// populate AZ output.
func azDescriptionAttributes(d *schema.ResourceData, zones []*ec2.AvailabilityZone) error {

d.SetId(resource.UniqueId())

var s []string

for _, v := range zones {
s = append(s, *v.ZoneName)
}
sort.Strings(s)
d.Set("availability_zones", s)
return nil
}

// Returns a set of tags.
func zoneMessages(m []*ec2.AvailabilityZoneMessage) []string {
var s []string
for _, v := range m {
s = append(s, *v.Message)
}
return s
}
48 changes: 48 additions & 0 deletions builtin/providers/aws/resource_aws_availability_zones_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSAvailabilityZones_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsAvailabilityZonesDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckAwsAvailabilityZonesConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsAvailabilityZonesID("aws_availability_zones.availability_zones"),
),
},
},
})
}

func testAccCheckAwsAvailabilityZonesDestroy(s *terraform.State) error {
return nil
}

func testAccCheckAwsAvailabilityZonesID(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find AZ resource: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("AZ resource ID not set")
}
return nil
}
}

const testAccCheckAwsAvailabilityZonesConfig = `
resource "aws_availability_zones" "availability_zones" {
}
`
17 changes: 17 additions & 0 deletions builtin/providers/aws/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -1097,3 +1097,20 @@ func sortInterfaceSlice(in []interface{}) []interface{} {

return b
}

// Build a slice of EC2 filter options from the filters provided.
func buildEc2Filters(set *schema.Set) []*ec2.Filter {
var filters []*ec2.Filter
for _, v := range set.List() {
m := v.(map[string]interface{})
var filterValues []*string
for _, e := range m["values"].([]interface{}) {
filterValues = append(filterValues, aws.String(e.(string)))
}
filters = append(filters, &ec2.Filter{
Name: aws.String(m["name"].(string)),
Values: filterValues,
})
}
return filters
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
layout: "aws"
page_title: "AWS: aws_availability_zones"
sidebar_current: "docs-aws-resource-availability-zones"
description: |-
Get the Availability Zones available to your account.
---

# aws\_availability\_zones

Get the Availability Zones available to your account.

## Example Usage
```
resource "aws_availability_zones" "availability_zones" {
filter {
name = "region-name"
values = ["us-east-1"]
}
zone_names = ["us-east-1a", "us-east-1c"]
}
```

~> **NOTE:** the example above is only shown to illustrate the available
options. During regular operation, it's recommended that you include a very
basic resource declaration, with no options, which will return the availability
zones assigned to your account within the region you are connected to.

## Argument Reference

The following arguments are supported:

* `filter` (optional): One or more name/value pairs to filter off of. There are
several valid keys, for a full reference, check out
[describe-availability-zones in the AWS CLI reference][1].

* `zone_names` (optional): A list of Availability Zones to directly filter for.

## Attribute Reference

* `id` - Automatically generated by Terraform (not for regular use).
* `availability_zones` - The list or returned availability zones.

[1]: http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-availability-zones.html
4 changes: 4 additions & 0 deletions website/source/layouts/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@
<a href="/docs/providers/aws/r/autoscaling_schedule.html">aws_autoscaling_schedule</a>
</li>

<li<%= sidebar_current("docs-aws-resource-availability-zones") %>>
<a href="/docs/providers/aws/r/availability_zones.html">aws_availability_zones</a>
</li>

<li<%= sidebar_current("docs-aws-resource-ebs-volume") %>>
<a href="/docs/providers/aws/r/ebs_volume.html">aws_ebs_volume</a>
</li>
Expand Down

0 comments on commit 4fb27ff

Please sign in to comment.