diff --git a/aws/data_source_aws_dynamodb_table.go b/aws/data_source_aws_dynamodb_table.go new file mode 100644 index 000000000000..4410feef4a2c --- /dev/null +++ b/aws/data_source_aws_dynamodb_table.go @@ -0,0 +1,193 @@ +package aws + +import ( + "bytes" + "fmt" + "log" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceAwsDynamoDbTable() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsDynamoDbTableRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "attribute": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + Set: func(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) + return hashcode.String(buf.String()) + }, + }, + "global_secondary_index": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "write_capacity": { + Type: schema.TypeInt, + Computed: true, + }, + "read_capacity": { + Type: schema.TypeInt, + Computed: true, + }, + "hash_key": { + Type: schema.TypeString, + Computed: true, + }, + "range_key": { + Type: schema.TypeString, + Computed: true, + }, + "projection_type": { + Type: schema.TypeString, + Computed: true, + }, + "non_key_attributes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + "hash_key": { + Type: schema.TypeString, + Computed: true, + }, + "local_secondary_index": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + }, + "range_key": { + Type: schema.TypeString, + Computed: true, + }, + "projection_type": { + Type: schema.TypeString, + Computed: true, + }, + "non_key_attributes": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + Set: func(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) + return hashcode.String(buf.String()) + }, + }, + "range_key": { + Type: schema.TypeString, + Computed: true, + }, + "read_capacity": { + Type: schema.TypeInt, + Computed: true, + }, + "stream_arn": { + Type: schema.TypeString, + Computed: true, + }, + "stream_enabled": { + Type: schema.TypeBool, + Computed: true, + }, + "stream_label": { + Type: schema.TypeString, + Computed: true, + }, + "stream_view_type": { + Type: schema.TypeString, + Computed: true, + StateFunc: func(v interface{}) string { + value := v.(string) + return strings.ToUpper(value) + }, + }, + "tags": tagsSchemaComputed(), + "ttl": { + Type: schema.TypeSet, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "attribute_name": { + Type: schema.TypeString, + Computed: true, + }, + "enabled": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "write_capacity": { + Type: schema.TypeInt, + Computed: true, + }, + }, + } +} + +func dataSourceAwsDynamoDbTableRead(d *schema.ResourceData, meta interface{}) error { + dynamodbconn := meta.(*AWSClient).dynamodbconn + log.Printf("[DEBUG] Loading data for DynamoDB table '%s'", d.Id()) + req := &dynamodb.DescribeTableInput{ + TableName: aws.String(d.Get("name").(string)), + } + + result, err := dynamodbconn.DescribeTable(req) + + if err != nil { + return errwrap.Wrapf("Error retrieving DynamoDB table: {{err}}", err) + } + + d.SetId(*result.Table.TableName) + + return flattenAwsDynamoDbTableResource(d, meta, result.Table) +} diff --git a/aws/data_source_aws_dynamodb_table_test.go b/aws/data_source_aws_dynamodb_table_test.go new file mode 100644 index 000000000000..11fe6687379d --- /dev/null +++ b/aws/data_source_aws_dynamodb_table_test.go @@ -0,0 +1,79 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccDataSourceAwsDynamoDbTable_basic(t *testing.T) { + tableName := fmt.Sprintf("testaccawsdynamodbtable-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsDynamoDbTableConfigBasic(tableName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "name", tableName), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "read_capacity", "20"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "write_capacity", "20"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "hash_key", "UserId"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "range_key", "GameTitle"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "attribute.#", "3"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "global_secondary_index.#", "1"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "tags.%", "2"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "tags.Name", "dynamodb-table-1"), + resource.TestCheckResourceAttr("data.aws_dynamodb_table.dynamodb_table_test", "tags.Environment", "test"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsDynamoDbTableConfigBasic(tableName string) string { + return fmt.Sprintf(`resource "aws_dynamodb_table" "dynamodb_table_test" { + name = "%s" + read_capacity = 20 + write_capacity = 20 + hash_key = "UserId" + range_key = "GameTitle" + + attribute { + name = "UserId" + type = "S" + } + + attribute { + name = "GameTitle" + type = "S" + } + + attribute { + name = "TopScore" + type = "N" + } + + global_secondary_index { + name = "GameTitleIndex" + hash_key = "GameTitle" + range_key = "TopScore" + write_capacity = 10 + read_capacity = 10 + projection_type = "INCLUDE" + non_key_attributes = ["UserId"] + } + + tags { + Name = "dynamodb-table-1" + Environment = "test" + } +} + +data "aws_dynamodb_table" "dynamodb_table_test" { + name = "${aws_dynamodb_table.dynamodb_table_test.name}" +}`, tableName) +} diff --git a/aws/provider.go b/aws/provider.go index f4e3c4f9bc03..77cff930b681 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -172,6 +172,7 @@ func Provider() terraform.ResourceProvider { "aws_cloudformation_stack": dataSourceAwsCloudFormationStack(), "aws_db_instance": dataSourceAwsDbInstance(), "aws_db_snapshot": dataSourceAwsDbSnapshot(), + "aws_dynamodb_table": dataSourceAwsDynamoDbTable(), "aws_ebs_snapshot": dataSourceAwsEbsSnapshot(), "aws_ebs_snapshot_ids": dataSourceAwsEbsSnapshotIds(), "aws_ebs_volume": dataSourceAwsEbsVolume(), diff --git a/aws/resource_aws_dynamodb_table.go b/aws/resource_aws_dynamodb_table.go index 1d558cf45b63..b33b940a0dcd 100644 --- a/aws/resource_aws_dynamodb_table.go +++ b/aws/resource_aws_dynamodb_table.go @@ -703,7 +703,11 @@ func resourceAwsDynamoDbTableRead(d *schema.ResourceData, meta interface{}) erro return err } - table := result.Table + return flattenAwsDynamoDbTableResource(d, meta, result.Table) +} + +func flattenAwsDynamoDbTableResource(d *schema.ResourceData, meta interface{}, table *dynamodb.TableDescription) error { + dynamodbconn := meta.(*AWSClient).dynamodbconn d.Set("write_capacity", table.ProvisionedThroughput.WriteCapacityUnits) d.Set("read_capacity", table.ProvisionedThroughput.ReadCapacityUnits) @@ -753,7 +757,7 @@ func resourceAwsDynamoDbTableRead(d *schema.ResourceData, meta interface{}) erro lsiList = append(lsiList, lsi) } - err = d.Set("local_secondary_index", lsiList) + err := d.Set("local_secondary_index", lsiList) if err != nil { return err } diff --git a/website/aws.erb b/website/aws.erb index 857dc699e5a2..c875448835c2 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -59,6 +59,9 @@ > aws_db_snapshot + > + aws_dynamodb_table + > aws_ebs_snapshot diff --git a/website/docs/d/dynamodb_table.html.markdown b/website/docs/d/dynamodb_table.html.markdown new file mode 100644 index 000000000000..6aab4f26577e --- /dev/null +++ b/website/docs/d/dynamodb_table.html.markdown @@ -0,0 +1,30 @@ +--- +layout: "aws" +page_title: "AWS: aws_dynamodb_table" +sidebar_current: "docs-aws-datasource-dynamodb-table" +description: |- + Provides a DynamoDB table data source. +--- + +# aws_dynamodb_table + +Provides information about a DynamoDB table. + +## Example Usage + +```hcl +data "aws_dynamodb_table" "tableName" { + name = "tableName" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the DynamoDB table. + +## Attributes Reference + +See the [DynamoDB Table Resource](/docs/providers/aws/r/dynamodb_table.html) for details on the +returned attributes - they are identical. \ No newline at end of file