From b75897651fe540eaddc4f69b60b6f98d50ef1fcb Mon Sep 17 00:00:00 2001 From: kt Date: Thu, 16 May 2019 15:07:19 -0700 Subject: [PATCH] New Resource: `azurerm_cosmosdb_mongo_collection` (#3459) fixes #548 --- azurerm/helpers/azure/cosmos.go | 23 +- azurerm/provider.go | 1 + ...ce_arm_cosmosdb_cassandra_keyspace_test.go | 14 +- .../resource_arm_cosmosdb_mongo_collection.go | 301 ++++++++++++++++++ ...urce_arm_cosmosdb_mongo_collection_test.go | 236 ++++++++++++++ ...source_arm_cosmosdb_mongo_database_test.go | 14 +- ...resource_arm_cosmosdb_sql_database_test.go | 14 +- azurerm/resource_arm_cosmosdb_table_test.go | 14 +- go.sum | 1 + website/azurerm.erb | 3 + .../r/cosmosdb_mongo_collection.html.markdown | 79 +++++ .../r/cosmosdb_mongo_database.html.markdown | 2 +- .../r/cosmosdb_sql_database.html.markdown | 2 +- 13 files changed, 666 insertions(+), 38 deletions(-) create mode 100644 azurerm/resource_arm_cosmosdb_mongo_collection.go create mode 100644 azurerm/resource_arm_cosmosdb_mongo_collection_test.go create mode 100644 website/docs/r/cosmosdb_mongo_collection.html.markdown diff --git a/azurerm/helpers/azure/cosmos.go b/azurerm/helpers/azure/cosmos.go index 216dddc94c4d..f7f21f8c743c 100644 --- a/azurerm/helpers/azure/cosmos.go +++ b/azurerm/helpers/azure/cosmos.go @@ -73,9 +73,21 @@ type CosmosDatabaseCollectionID struct { Collection string } -type CosmosDatabaseContainerID struct { - CosmosDatabaseID - Container string +func ParseCosmosDatabaseCollectionID(id string) (*CosmosDatabaseCollectionID, error) { + subid, err := ParseCosmosDatabaseID(id) + if err != nil { + return nil, err + } + + collection, ok := subid.Path["collections"] + if !ok { + return nil, fmt.Errorf("Error: Unable to parse Cosmos Database Resource ID: collections is missing from: %s", id) + } + + return &CosmosDatabaseCollectionID{ + CosmosDatabaseID: *subid, + Collection: collection, + }, nil } type CosmosKeyspaceID struct { @@ -100,11 +112,6 @@ func ParseCosmosKeyspaceID(id string) (*CosmosKeyspaceID, error) { }, nil } -type CosmosKeyspaceTableID struct { - CosmosKeyspaceID - Table string -} - type CosmosTableID struct { CosmosAccountID Table string diff --git a/azurerm/provider.go b/azurerm/provider.go index 44e92655b0a7..b591826a20b4 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -236,6 +236,7 @@ func Provider() terraform.ResourceProvider { "azurerm_container_service": resourceArmContainerService(), "azurerm_cosmosdb_account": resourceArmCosmosDbAccount(), "azurerm_cosmosdb_cassandra_keyspace": resourceArmCosmosDbCassandraKeyspace(), + "azurerm_cosmosdb_mongo_collection": resourceArmCosmosDbMongoCollection(), "azurerm_cosmosdb_mongo_database": resourceArmCosmosDbMongoDatabase(), "azurerm_cosmosdb_sql_database": resourceArmCosmosDbSQLDatabase(), "azurerm_cosmosdb_table": resourceArmCosmosDbTable(), diff --git a/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go b/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go index 6d0bcf5bcbbc..83c151a92226 100644 --- a/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go +++ b/azurerm/resource_arm_cosmosdb_cassandra_keyspace_test.go @@ -11,19 +11,19 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMCosmosCassandraKeyspace_basic(t *testing.T) { +func TestAccAzureRMCosmosDbCassandraKeyspace_basic(t *testing.T) { ri := tf.AccRandTimeInt() resourceName := "azurerm_cosmosdb_cassandra_keyspace.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosCassandraKeyspaceDestroy, + CheckDestroy: testCheckAzureRMCosmosDbCassandraKeyspaceDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMCosmosCassandraKeyspace_basic(ri, testLocation()), + Config: testAccAzureRMCosmosDbCassandraKeyspace_basic(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( - testCheckAzureRMCosmosCassandraKeyspaceExists(resourceName), + testCheckAzureRMCosmosDbCassandraKeyspaceExists(resourceName), ), }, { @@ -35,7 +35,7 @@ func TestAccAzureRMCosmosCassandraKeyspace_basic(t *testing.T) { }) } -func testCheckAzureRMCosmosCassandraKeyspaceDestroy(s *terraform.State) error { +func testCheckAzureRMCosmosDbCassandraKeyspaceDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -63,7 +63,7 @@ func testCheckAzureRMCosmosCassandraKeyspaceDestroy(s *terraform.State) error { return nil } -func testCheckAzureRMCosmosCassandraKeyspaceExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMCosmosDbCassandraKeyspaceExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -91,7 +91,7 @@ func testCheckAzureRMCosmosCassandraKeyspaceExists(resourceName string) resource } } -func testAccAzureRMCosmosCassandraKeyspace_basic(rInt int, location string) string { +func testAccAzureRMCosmosDbCassandraKeyspace_basic(rInt int, location string) string { return fmt.Sprintf(` %[1]s diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go new file mode 100644 index 000000000000..788e43702a20 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -0,0 +1,301 @@ +package azurerm + +import ( + "fmt" + "log" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmCosmosDbMongoCollection() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCosmosDbMongoCollectionCreateUpdate, + Read: resourceArmCosmosDbMongoCollectionRead, + Update: resourceArmCosmosDbMongoCollectionCreateUpdate, + Delete: resourceArmCosmosDbMongoCollectionDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": resourceGroupNameSchema(), + + "account_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + + "database_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + // SDK/api accepts an array.. but only one is allowed + "shard_key": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + // default TTL is simply an index on _ts with expireAfterOption, given we can't seem to set TTLs on a given index lets expose this to match the portal + "default_ttl_seconds": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(-1), + }, + + "indexes": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, // this is a list in the SDK/API, however any more then a single value causes a 404 + Required: true, + ValidateFunc: validate.NoEmptyStrings, + }, + + "unique": { + Type: schema.TypeBool, + Optional: true, + Default: true, // portal defaults to true + }, + + // expire_after_seconds is only allowed on `_ts`: + // Unable to parse request payload due to the following reason: 'The 'expireAfterSeconds' option is supported on '_ts' field only. + }, + }, + }, + }, + } +} + +func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmosAccountsClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + account := d.Get("account_name").(string) + database := d.Get("database_name").(string) + + if requireResourcesToBeImported && d.IsNewResource() { + existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Mongo Collection %s (Account %s, Database %s)", name, account, database) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) + } + } + + var ttl *int + if v, ok := d.GetOkExists("default_ttl_seconds"); ok { + ttl = utils.Int(v.(int)) + } + + db := documentdb.MongoDBCollectionCreateUpdateParameters{ + MongoDBCollectionCreateUpdateProperties: &documentdb.MongoDBCollectionCreateUpdateProperties{ + Resource: &documentdb.MongoDBCollectionResource{ + ID: &name, + Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), + }, + Options: map[string]*string{}, + }, + } + + if v, ok := d.GetOkExists("shard_key"); ok { + db.MongoDBCollectionCreateUpdateProperties.Resource.ShardKey = map[string]*string{ + v.(string): utils.String("Hash"), // looks like only hash is supported for now + } + } + + future, err := client.CreateUpdateMongoDBCollection(ctx, resourceGroup, account, database, name, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error getting ID for Cosmos Mongo Collection %s (Account %s, Database %s) ID: %v", name, account, database, err) + } + d.SetId(id) + + return resourceArmCosmosDbMongoCollectionRead(d, meta) +} + +func resourceArmCosmosDbMongoCollectionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmosAccountsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseCollectionID(d.Id()) + if err != nil { + return err + } + + resp, err := client.GetMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] Error reading Cosmos Mongo Collection %s (Account %s, Database %s)", id.Collection, id.Account, id.Database) + d.SetId("") + return nil + } + + return fmt.Errorf("Error reading Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) + d.Set("database_name", id.Database) + if props := resp.MongoDBCollectionProperties; props != nil { + d.Set("name", props.ID) + + // you can only have one + if len(props.ShardKey) > 2 { + return fmt.Errorf("unexpected number of shard keys: %d", len(props.ShardKey)) + } + + for k := range props.ShardKey { + d.Set("shard_key", k) + } + + indexes, ttl := flattenCosmosMongoCollectionIndexes(props.Indexes) + d.Set("default_ttl_seconds", ttl) + if err := d.Set("indexes", indexes); err != nil { + return fmt.Errorf("Error setting `indexes`: %+v", err) + } + + } + + return nil +} + +func resourceArmCosmosDbMongoCollectionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cosmosAccountsClient + ctx := meta.(*ArmClient).StopContext + + id, err := azure.ParseCosmosDatabaseCollectionID(d.Id()) + if err != nil { + return err + } + + future, err := client.DeleteMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) + if err != nil { + if !response.WasNotFound(future.Response()) { + return fmt.Errorf("Error deleting Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + } + + err = future.WaitForCompletionRef(ctx, client.Client) + if err != nil { + return fmt.Errorf("Error waiting on delete future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + + return nil +} + +func expandCosmosMongoCollectionIndexes(input interface{}, defaultTtl *int) *[]documentdb.MongoIndex { + outputs := make([]documentdb.MongoIndex, 0) + + for _, i := range input.(*schema.Set).List() { + b := i.(map[string]interface{}) + outputs = append(outputs, documentdb.MongoIndex{ + Key: &documentdb.MongoIndexKeys{ + Keys: &[]string{b["key"].(string)}, + }, + Options: &documentdb.MongoIndexOptions{ + Unique: utils.Bool(b["unique"].(bool)), + }, + }) + } + + if defaultTtl != nil { + outputs = append(outputs, documentdb.MongoIndex{ + Key: &documentdb.MongoIndexKeys{ + Keys: &[]string{"_ts"}, + }, + Options: &documentdb.MongoIndexOptions{ + ExpireAfterSeconds: utils.Int32(int32(*defaultTtl)), + }, + }) + } + + return &outputs +} + +func flattenCosmosMongoCollectionIndexes(indexes *[]documentdb.MongoIndex) (*[]map[string]interface{}, *int) { + slice := make([]map[string]interface{}, 0) + + var ttl int + for _, i := range *indexes { + if key := i.Key; key != nil { + m := map[string]interface{}{} + var ttlInner int32 + + if options := i.Options; options != nil { + if v := options.Unique; v != nil { + m["unique"] = *v + } else { + m["unique"] = false // todo required? API sends back nothing for false + } + + if v := options.ExpireAfterSeconds; v != nil { + ttlInner = *v + } + } + + if keys := key.Keys; keys != nil && len(*keys) > 0 { + k := (*keys)[0] + + if !strings.HasPrefix(k, "_") && k != "DocumentDBDefaultIndex" { // lets ignore system properties? + m["key"] = k + + // only append indexes with a non system key + slice = append(slice, m) + } + + if k == "_ts" { + ttl = int(ttlInner) + } + } + } + } + + return &slice, &ttl +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go new file mode 100644 index 000000000000..8313d50fa7b2 --- /dev/null +++ b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go @@ -0,0 +1,236 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMCosmosDbMongoCollection_basic(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbMongoCollection_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), + resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), + resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + ), + }, + { + Config: testAccAzureRMCosmosDbMongoCollection_complete(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), + resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), + resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMCosmosDbMongoCollection_updated(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "70707"), + resource.TestCheckResourceAttr(resourceName, "indexes.#", "3"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckAzureRMCosmosDbMongoCollectionDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cosmosdb_mongo_collection" { + continue + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + database := rs.Primary.Attributes["database_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Error checking destroy for Cosmos Mongo Collection %s (account %s, database %s) still exists:\n%v", name, account, database, err) + } + } + + if !utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Cosmos Mongo Collection %s (account %s) still exists:\n%#v", name, account, resp) + } + } + + return nil +} + +func testCheckAzureRMCosmosDbMongoCollectionExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient + ctx := testAccProvider.Meta().(*ArmClient).StopContext + + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + name := rs.Primary.Attributes["name"] + account := rs.Primary.Attributes["account_name"] + database := rs.Primary.Attributes["database_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + return fmt.Errorf("Bad: Get on cosmosAccountsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Cosmos database '%s' (account: '%s', database: %s) does not exist", name, account, database) + } + + return nil + } +} + +func testAccAzureRMCosmosDbMongoCollection_basic(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) +} + +func testAccAzureRMCosmosDbMongoCollection_complete(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + + default_ttl_seconds = 707 + shard_key = "day" + + indexes { + key = "seven" + unique = false + } + + indexes { + key = "day" + unique = true + } +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) +} + +func testAccAzureRMCosmosDbMongoCollection_updated(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + + default_ttl_seconds = 70707 + + indexes { + key = "seven" + unique = true + } + + indexes { + key = "day" + unique = false + } + + indexes { + key = "fool" + unique = false + } +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_database_test.go b/azurerm/resource_arm_cosmosdb_mongo_database_test.go index 448e6662bffc..f5cbcc4b5d4d 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database_test.go @@ -11,19 +11,19 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMCosmosMongoDatabase_basic(t *testing.T) { +func TestAccAzureRMCosmosDbMongoDatabase_basic(t *testing.T) { ri := tf.AccRandTimeInt() resourceName := "azurerm_cosmosdb_mongo_database.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosMongoDatabaseDestroy, + CheckDestroy: testCheckAzureRMCosmosDbMongoDatabaseDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMCosmosMongoDatabase_basic(ri, testLocation()), + Config: testAccAzureRMCosmosDbMongoDatabase_basic(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( - testCheckAzureRMCosmosMongoDatabaseExists(resourceName), + testCheckAzureRMCosmosDbMongoDatabaseExists(resourceName), ), }, { @@ -35,7 +35,7 @@ func TestAccAzureRMCosmosMongoDatabase_basic(t *testing.T) { }) } -func testCheckAzureRMCosmosMongoDatabaseDestroy(s *terraform.State) error { +func testCheckAzureRMCosmosDbMongoDatabaseDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -63,7 +63,7 @@ func testCheckAzureRMCosmosMongoDatabaseDestroy(s *terraform.State) error { return nil } -func testCheckAzureRMCosmosMongoDatabaseExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMCosmosDbMongoDatabaseExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -91,7 +91,7 @@ func testCheckAzureRMCosmosMongoDatabaseExists(resourceName string) resource.Tes } } -func testAccAzureRMCosmosMongoDatabase_basic(rInt int, location string) string { +func testAccAzureRMCosmosDbMongoDatabase_basic(rInt int, location string) string { return fmt.Sprintf(` %[1]s diff --git a/azurerm/resource_arm_cosmosdb_sql_database_test.go b/azurerm/resource_arm_cosmosdb_sql_database_test.go index b84d9b3ad355..2f1323473d8d 100644 --- a/azurerm/resource_arm_cosmosdb_sql_database_test.go +++ b/azurerm/resource_arm_cosmosdb_sql_database_test.go @@ -12,19 +12,19 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMCosmosSQLDatabase_basic(t *testing.T) { +func TestAccAzureRMCosmosDbSqlDatabase_basic(t *testing.T) { ri := tf.AccRandTimeInt() resourceName := "azurerm_cosmosdb_sql_database.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosSQLDatabaseDestroy, + CheckDestroy: testCheckAzureRMCosmosDbSqlDatabaseDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMCosmosSQLDatabase_basic(ri, testLocation()), + Config: testAccAzureRMCosmosDbSqlDatabase_basic(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( - testCheckAzureRMCosmosSQLDatabaseExists(resourceName), + testCheckAzureRMCosmosDbSqlDatabaseExists(resourceName), ), }, { @@ -36,7 +36,7 @@ func TestAccAzureRMCosmosSQLDatabase_basic(t *testing.T) { }) } -func testCheckAzureRMCosmosSQLDatabaseDestroy(s *terraform.State) error { +func testCheckAzureRMCosmosDbSqlDatabaseDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -64,7 +64,7 @@ func testCheckAzureRMCosmosSQLDatabaseDestroy(s *terraform.State) error { return nil } -func testCheckAzureRMCosmosSQLDatabaseExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMCosmosDbSqlDatabaseExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -92,7 +92,7 @@ func testCheckAzureRMCosmosSQLDatabaseExists(resourceName string) resource.TestC } } -func testAccAzureRMCosmosSQLDatabase_basic(rInt int, location string) string { +func testAccAzureRMCosmosDbSqlDatabase_basic(rInt int, location string) string { return fmt.Sprintf(` %[1]s diff --git a/azurerm/resource_arm_cosmosdb_table_test.go b/azurerm/resource_arm_cosmosdb_table_test.go index cce96d646e17..bb3475f60f10 100644 --- a/azurerm/resource_arm_cosmosdb_table_test.go +++ b/azurerm/resource_arm_cosmosdb_table_test.go @@ -11,19 +11,19 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" ) -func TestAccAzureRMCosmosTable_basic(t *testing.T) { +func TestAccAzureRMCosmosDbTable_basic(t *testing.T) { ri := tf.AccRandTimeInt() resourceName := "azurerm_cosmosdb_table.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testCheckAzureRMCosmosTableDestroy, + CheckDestroy: testCheckAzureRMCosmosDbTableDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMCosmosTable_basic(ri, testLocation()), + Config: testAccAzureRMCosmosDbTable_basic(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( - testCheckAzureRMCosmosTableExists(resourceName), + testCheckAzureRMCosmosDbTableExists(resourceName), ), }, { @@ -35,7 +35,7 @@ func TestAccAzureRMCosmosTable_basic(t *testing.T) { }) } -func testCheckAzureRMCosmosTableDestroy(s *terraform.State) error { +func testCheckAzureRMCosmosDbTableDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -63,7 +63,7 @@ func testCheckAzureRMCosmosTableDestroy(s *terraform.State) error { return nil } -func testCheckAzureRMCosmosTableExists(resourceName string) resource.TestCheckFunc { +func testCheckAzureRMCosmosDbTableExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).cosmosAccountsClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -91,7 +91,7 @@ func testCheckAzureRMCosmosTableExists(resourceName string) resource.TestCheckFu } } -func testAccAzureRMCosmosTable_basic(rInt int, location string) string { +func testAccAzureRMCosmosDbTable_basic(rInt int, location string) string { return fmt.Sprintf(` %[1]s diff --git a/go.sum b/go.sum index c7105755d4b5..d476ae604973 100644 --- a/go.sum +++ b/go.sum @@ -437,6 +437,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jY golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/website/azurerm.erb b/website/azurerm.erb index 21a53f6e859d..5120cc39c810 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -699,6 +699,9 @@ > azurerm_cosmosdb_cassandra_keyspace + > + azurerm_cosmosdb_mongo_collection + > azurerm_cosmosdb_mongo_database diff --git a/website/docs/r/cosmosdb_mongo_collection.html.markdown b/website/docs/r/cosmosdb_mongo_collection.html.markdown new file mode 100644 index 000000000000..6de723275d78 --- /dev/null +++ b/website/docs/r/cosmosdb_mongo_collection.html.markdown @@ -0,0 +1,79 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_mongo_collection" +sidebar_current: "docs-azurerm-resource-cosmosdb-mongo-collection" +description: |- + Manages a Mongo Collection within a Cosmos DB Account. +--- + +# azurerm_cosmosdb_mongo_collection + +Manages a Mongo Collection within a Cosmos DB Account. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_account" "example" { + name = "tfex-cosmosdb-account" + resource_group_name = "tfex-cosmosdb-account-rg" +} + +resource "azurerm_cosmosdb_mongo_database" "example" { + name = "tfex-cosmos-mongo-db" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" +} +resource "azurerm_cosmosdb_mongo_collection" "example" { + name = "tfex-cosmos-mongo-db" + resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" + account_name = "${data.azurerm_cosmosdb_account.example.name}" + database_name = "${data.azurerm_cosmosdb_account.example.name}" + + default_ttl_seconds = "777" + shard_key = "uniqueKey" + + indexes { + key = "aKey" + unique = false + } + + indexes { + key = "uniqueKey" + unique = true + } +} + + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the Cosmos DB Mongo Collection. Changing this forces a new resource to be created. +* `resource_group_name` - (Required) The name of the resource group in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created. +* `resource_group_name` - (Required) The name of the Cosmos DB Mongo Database in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created. +* `default_ttl_seconds` - (Required) The default Time To Live in seconds. If the value is `-1` items are not automatically expired. +* `shard_key` - (Required) The name of the key to partition on for sharding. There must not be any other unique index keys. +* `indexes` - (Optional) One or more `indexes` blocks as defined below. + +--- + +An `indexes` block supports the following: + +* `key` - (Required) The name of the key to use for this index. +* `unique` - (Required) Whether the index key should be unique. + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Cosmos DB Mongo Collection ID. + +## Import + +Cosmos DB Mongo Collection can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_cosmosdb_mongo_collection.collection1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/mongodb/databases/db1/collections/collection1 +``` diff --git a/website/docs/r/cosmosdb_mongo_database.html.markdown b/website/docs/r/cosmosdb_mongo_database.html.markdown index 8ba2543a74f3..e9e8b5c744c4 100644 --- a/website/docs/r/cosmosdb_mongo_database.html.markdown +++ b/website/docs/r/cosmosdb_mongo_database.html.markdown @@ -44,7 +44,7 @@ The following attributes are exported: ## Import -Cosmos Mongo KeySpace can be imported using the `resource id`, e.g. +Cosmos Mongo Database can be imported using the `resource id`, e.g. ```shell terraform import azurerm_cosmosdb_mongo_database.db1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/mongodb/databases/db1 diff --git a/website/docs/r/cosmosdb_sql_database.html.markdown b/website/docs/r/cosmosdb_sql_database.html.markdown index ec8d903249de..d2f7980e5c59 100644 --- a/website/docs/r/cosmosdb_sql_database.html.markdown +++ b/website/docs/r/cosmosdb_sql_database.html.markdown @@ -44,7 +44,7 @@ The following attributes are exported: ## Import -Cosmos SQL KeySpace can be imported using the `resource id`, e.g. +Cosmos SQL Database can be imported using the `resource id`, e.g. ```shell terraform import azurerm_cosmosdb_sql_database.db1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/account1/apis/sql/databases/db1