Skip to content

Commit

Permalink
Merge pull request #1961 from pgavlin/virtualNetworkRules
Browse files Browse the repository at this point in the history
Add support for vnet rules to CosmosDB accounts.
  • Loading branch information
katbyte authored Sep 21, 2018
2 parents f8aa0c5 + d5a07c5 commit 9b9995b
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 13 deletions.
37 changes: 37 additions & 0 deletions azurerm/data_source_cosmos_db_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,24 @@ func dataSourceArmCosmosDBAccount() *schema.Resource {
},
},

"is_virtual_network_filter_enabled": {
Type: schema.TypeBool,
Computed: true,
},

"virtual_network_rule": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

"endpoint": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -183,6 +201,7 @@ func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{})
d.Set("offer_type", string(props.DatabaseAccountOfferType))
d.Set("ip_range_filter", props.IPRangeFilter)
d.Set("endpoint", props.DocumentEndpoint)
d.Set("is_virtual_network_filter_enabled", resp.IsVirtualNetworkFilterEnabled)
d.Set("enable_automatic_failover", resp.EnableAutomaticFailover)

if err := d.Set("consistency_policy", flattenAzureRmCosmosDBAccountConsistencyPolicy(resp.ConsistencyPolicy)); err != nil {
Expand All @@ -206,6 +225,10 @@ func dataSourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{})
return fmt.Errorf("Error setting `capabilities`: %+v", err)
}

if err := d.Set("virtual_network_rule", flattenAzureRmCosmosDBAccountVirtualNetworkRulesAsList(props.VirtualNetworkRules)); err != nil {
return fmt.Errorf("Error setting `virtual_network_rule`: %+v", err)
}

readEndpoints := make([]string, 0)
if locations := props.ReadLocations; locations != nil {
for _, l := range *locations {
Expand Down Expand Up @@ -256,3 +279,17 @@ func flattenAzureRmCosmosDBAccountCapabilitiesAsList(capabilities *[]documentdb.

return &slice
}

func flattenAzureRmCosmosDBAccountVirtualNetworkRulesAsList(rules *[]documentdb.VirtualNetworkRule) []map[string]interface{} {
if rules == nil {
return []map[string]interface{}{}
}

virtualNetworkRules := make([]map[string]interface{}, len(*rules))
for i, r := range *rules {
virtualNetworkRules[i] = map[string]interface{}{
"id": *r.ID,
}
}
return virtualNetworkRules
}
33 changes: 33 additions & 0 deletions azurerm/data_source_cosmos_db_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ func TestAccDataSourceAzureRMCosmosDBAccount_geoReplicated_customId(t *testing.T
})
}

func TestAccDataSourceAzureRMCosmosDBAccount_virtualNetworkFilter(t *testing.T) {
ri := acctest.RandInt()
dataSourceName := "data.azurerm_cosmosdb_account.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAzureRMCosmosDBAccount_virtualNetworkFilter(ri, testLocation()),
Check: resource.ComposeAggregateTestCheckFunc(
checkAccAzureRMCosmosDBAccount_basic(dataSourceName, testLocation(), string(documentdb.BoundedStaleness), 1),
resource.TestCheckResourceAttr(dataSourceName, "is_virtual_network_filter_enabled", "true"),
resource.TestCheckResourceAttrSet(dataSourceName, "virtual_network_rule.0.id"),
resource.TestCheckResourceAttrSet(dataSourceName, "virtual_network_rule.1.id"),
),
},
},
})
}

func TestAccDataSourceAzureRMCosmosDBAccount_complete(t *testing.T) {
ri := acctest.RandInt()
dataSourceName := "data.azurerm_cosmosdb_account.test"
Expand Down Expand Up @@ -110,3 +132,14 @@ data "azurerm_cosmosdb_account" "test" {
}
`, testAccAzureRMCosmosDBAccount_complete(rInt, location, altLocation))
}

func testAccDataSourceAzureRMCosmosDBAccount_virtualNetworkFilter(rInt int, location string) string {
return fmt.Sprintf(`
%s
data "azurerm_cosmosdb_account" "test" {
name = "${azurerm_cosmosdb_account.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
`, testAccAzureRMCosmosDBAccount_virtualNetworkFilter(rInt, location))
}
101 changes: 88 additions & 13 deletions azurerm/resource_arm_cosmos_db_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import (
"fmt"
"log"
"regexp"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb"

"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"

"github.com/hashicorp/terraform/helper/schema"
"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/utils"
)
Expand Down Expand Up @@ -205,6 +207,27 @@ func resourceArmCosmosDBAccount() *schema.Resource {
Set: resourceAzureRMCosmosDBAccountCapabilitiesHash,
},

"is_virtual_network_filter_enabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},

"virtual_network_rule": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: azure.ValidateResourceID,
},
},
},
Set: resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash,
},

//computed
"endpoint": {
Type: schema.TypeString,
Expand Down Expand Up @@ -275,6 +298,7 @@ func resourceArmCosmosDBAccountCreate(d *schema.ResourceData, meta interface{})
kind := d.Get("kind").(string)
offerType := d.Get("offer_type").(string)
ipRangeFilter := d.Get("ip_range_filter").(string)
isVirtualNetworkFilterEnabled := d.Get("is_virtual_network_filter_enabled").(bool)
enableAutomaticFailover := d.Get("enable_automatic_failover").(bool)

r, err := client.CheckNameExists(ctx, name)
Expand Down Expand Up @@ -306,12 +330,14 @@ func resourceArmCosmosDBAccountCreate(d *schema.ResourceData, meta interface{})
Location: utils.String(location),
Kind: documentdb.DatabaseAccountKind(kind),
DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{
DatabaseAccountOfferType: utils.String(offerType),
IPRangeFilter: utils.String(ipRangeFilter),
EnableAutomaticFailover: utils.Bool(enableAutomaticFailover),
ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d),
Locations: &geoLocations,
Capabilities: expandAzureRmCosmosDBAccountCapabilities(d),
DatabaseAccountOfferType: utils.String(offerType),
IPRangeFilter: utils.String(ipRangeFilter),
IsVirtualNetworkFilterEnabled: utils.Bool(isVirtualNetworkFilterEnabled),
EnableAutomaticFailover: utils.Bool(enableAutomaticFailover),
ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d),
Locations: &geoLocations,
Capabilities: expandAzureRmCosmosDBAccountCapabilities(d),
VirtualNetworkRules: expandAzureRmCosmosDBAccountVirtualNetworkRules(d),
},
Tags: expandTags(tags),
}
Expand Down Expand Up @@ -345,6 +371,7 @@ func resourceArmCosmosDBAccountUpdate(d *schema.ResourceData, meta interface{})
kind := d.Get("kind").(string)
offerType := d.Get("offer_type").(string)
ipRangeFilter := d.Get("ip_range_filter").(string)
isVirtualNetworkFilterEnabled := d.Get("is_virtual_network_filter_enabled").(bool)
enableAutomaticFailover := d.Get("enable_automatic_failover").(bool)

//hacky, todo fix up once deprecated field 'failover_policy' is removed
Expand Down Expand Up @@ -390,12 +417,14 @@ func resourceArmCosmosDBAccountUpdate(d *schema.ResourceData, meta interface{})
Location: utils.String(location),
Kind: documentdb.DatabaseAccountKind(kind),
DatabaseAccountCreateUpdateProperties: &documentdb.DatabaseAccountCreateUpdateProperties{
DatabaseAccountOfferType: utils.String(offerType),
IPRangeFilter: utils.String(ipRangeFilter),
EnableAutomaticFailover: utils.Bool(enableAutomaticFailover),
Capabilities: expandAzureRmCosmosDBAccountCapabilities(d),
ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d),
Locations: &oldLocations,
DatabaseAccountOfferType: utils.String(offerType),
IPRangeFilter: utils.String(ipRangeFilter),
IsVirtualNetworkFilterEnabled: utils.Bool(isVirtualNetworkFilterEnabled),
EnableAutomaticFailover: utils.Bool(enableAutomaticFailover),
Capabilities: expandAzureRmCosmosDBAccountCapabilities(d),
ConsistencyPolicy: expandAzureRmCosmosDBAccountConsistencyPolicy(d),
Locations: &oldLocations,
VirtualNetworkRules: expandAzureRmCosmosDBAccountVirtualNetworkRules(d),
},
Tags: expandTags(tags),
}
Expand Down Expand Up @@ -493,6 +522,10 @@ func resourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) er
d.Set("ip_range_filter", resp.IPRangeFilter)
d.Set("endpoint", resp.DocumentEndpoint)

if v := resp.IsVirtualNetworkFilterEnabled; v != nil {
d.Set("is_virtual_network_filter_enabled", resp.IsVirtualNetworkFilterEnabled)
}

if v := resp.EnableAutomaticFailover; v != nil {
d.Set("enable_automatic_failover", resp.EnableAutomaticFailover)
}
Expand All @@ -515,6 +548,10 @@ func resourceArmCosmosDBAccountRead(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("Error setting `capabilities`: %+v", err)
}

if err := d.Set("virtual_network_rule", flattenAzureRmCosmosDBAccountVirtualNetworkRules(resp.VirtualNetworkRules)); err != nil {
return fmt.Errorf("Error setting `virtual_network_rule`: %+v", err)
}

if p := resp.ReadLocations; p != nil {
readEndpoints := []string{}
for _, l := range *p {
Expand Down Expand Up @@ -790,6 +827,17 @@ func expandAzureRmCosmosDBAccountCapabilities(d *schema.ResourceData) *[]documen
return &s
}

func expandAzureRmCosmosDBAccountVirtualNetworkRules(d *schema.ResourceData) *[]documentdb.VirtualNetworkRule {
virtualNetworkRules := d.Get("virtual_network_rule").(*schema.Set).List()

s := make([]documentdb.VirtualNetworkRule, len(virtualNetworkRules))
for i, r := range virtualNetworkRules {
m := r.(map[string]interface{})
s[i] = documentdb.VirtualNetworkRule{ID: utils.String(m["id"].(string))}
}
return &s
}

func flattenAzureRmCosmosDBAccountConsistencyPolicy(policy *documentdb.ConsistencyPolicy) []interface{} {

result := map[string]interface{}{}
Expand Down Expand Up @@ -873,6 +921,23 @@ func flattenAzureRmCosmosDBAccountCapabilities(capabilities *[]documentdb.Capabi
return &s
}

func flattenAzureRmCosmosDBAccountVirtualNetworkRules(rules *[]documentdb.VirtualNetworkRule) *schema.Set {
results := schema.Set{
F: resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash,
}

if rules != nil {
for _, r := range *rules {
rule := map[string]interface{}{
"id": *r.ID,
}
results.Add(rule)
}
}

return &results
}

//todo remove once deprecated field `failover_policy` is removed
func resourceAzureRMCosmosDBAccountFailoverPolicyHash(v interface{}) int {
var buf bytes.Buffer
Expand Down Expand Up @@ -913,3 +978,13 @@ func resourceAzureRMCosmosDBAccountCapabilitiesHash(v interface{}) int {

return hashcode.String(buf.String())
}

func resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash(v interface{}) int {
var buf bytes.Buffer

if m, ok := v.(map[string]interface{}); ok {
buf.WriteString(strings.ToLower(m["id"].(string)))
}

return hashcode.String(buf.String())
}
64 changes: 64 additions & 0 deletions azurerm/resource_arm_cosmos_db_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,28 @@ func TestAccAzureRMCosmosDBAccount_geoReplicated_rename(t *testing.T) {
})
}

func TestAccAzureRMCosmosDBAccount_virtualNetworkFilter(t *testing.T) {
ri := acctest.RandInt()
resourceName := "azurerm_cosmosdb_account.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMCosmosDBAccountDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMCosmosDBAccount_virtualNetworkFilter(ri, testLocation()),
Check: checkAccAzureRMCosmosDBAccount_basic(resourceName, testLocation(), string(documentdb.BoundedStaleness), 1),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

//basic --> complete (
func TestAccAzureRMCosmosDBAccount_complete(t *testing.T) {
ri := acctest.RandInt()
Expand Down Expand Up @@ -608,6 +630,48 @@ func testAccAzureRMCosmosDBAccount_complete(rInt int, location string, altLocati
`, rInt, altLocation))
}

func testAccAzureRMCosmosDBAccount_virtualNetworkFilter(rInt int, location string) string {
vnetConfig := fmt.Sprintf(`
resource "azurerm_virtual_network" "test" {
name = "acctest-%[1]d"
resource_group_name = "${azurerm_resource_group.test.name}"
address_space = ["10.0.0.0/16"]
location = "${azurerm_resource_group.test.location}"
dns_servers = ["10.0.0.4", "10.0.0.5"]
}
resource "azurerm_subnet" "subnet1" {
name = "acctest-%[1]d-1"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.0.1.0/24"
service_endpoints = ["Microsoft.AzureCosmosDB"]
}
resource "azurerm_subnet" "subnet2" {
name = "acctest-%[1]d-2"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.0.2.0/24"
service_endpoints = ["Microsoft.AzureCosmosDB"]
}
`, rInt)

basic := testAccAzureRMCosmosDBAccount_basic(rInt, location, string(documentdb.BoundedStaleness), "", `
is_virtual_network_filter_enabled = true
virtual_network_rule {
id = "${azurerm_subnet.subnet1.id}"
}
virtual_network_rule {
id = "${azurerm_subnet.subnet2.id}"
}
`)

return vnetConfig + basic
}

func checkAccAzureRMCosmosDBAccount_basic(resourceName string, location string, consistency string, locationCount int) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
testCheckAzureRMCosmosDBAccountExists(resourceName),
Expand Down
8 changes: 8 additions & 0 deletions website/docs/d/cosmosdb_account.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ The following attributes are exported:

* `capabilities` - Capabilities enabled on this Cosmos DB account.

* `is_virtual_network_filter_enabled` - If virtual network filtering is enabled for this Cosmos DB account.

* `virtual_network_rule` - Subnets that are allowed to access this CosmosDB account.

`consistency_policy` The current consistency Settings for this CosmosDB account with the following properties:

* `consistency_level` - The Consistency Level used by this CosmosDB Account.
Expand All @@ -64,6 +68,10 @@ The following attributes are exported:
* `location` - The name of the Azure region hosting replicated data.
* `priority` - The locations fail over priority.

`virtual_network_rule` The virtual network subnets allowed to access this Cosmos DB account with the following properties:

* `id` - The ID of the virtual network subnet.

* `endpoint` - The endpoint used to connect to the CosmosDB account.

* `read_endpoints` - A list of read endpoints available for this CosmosDB account.
Expand Down
Loading

0 comments on commit 9b9995b

Please sign in to comment.