[MS] provider/azurerm: Data Source for Azure Resource Group (#15022)
* Data Source support for Resource Group * Better message for mismatching locations. * Reuse existing read code * Adds documentation * Adds test * Adds a function for composing ID strings * Change location to computed.
This commit is contained in:
parent
d587b68863
commit
b465b01355
|
@ -0,0 +1,44 @@
|
||||||
|
package azurerm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceArmResourceGroup() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Read: dataSourceArmResourceGroupRead,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"location": locationForDataSourceSchema(),
|
||||||
|
"tags": tagsForDataSourceSchema(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceArmResourceGroupRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
armClient := meta.(*ArmClient)
|
||||||
|
|
||||||
|
resourceGroupName := d.Get("name").(string)
|
||||||
|
resourceId := &ResourceID{
|
||||||
|
SubscriptionID: armClient.subscriptionId,
|
||||||
|
ResourceGroup: resourceGroupName,
|
||||||
|
}
|
||||||
|
resourceIdString, err := composeAzureResourceID(resourceId)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(resourceIdString)
|
||||||
|
|
||||||
|
if err := resourceArmResourceGroupRead(d, meta); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package azurerm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccDataSourceAzureRMResourceGroup_basic(t *testing.T) {
|
||||||
|
ri := acctest.RandInt()
|
||||||
|
name := fmt.Sprintf("acctestRg_%d", ri)
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccDataSourceAzureRMResourceGroupBasic(name),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr("data.azurerm_resource_group.test", "name", name),
|
||||||
|
resource.TestCheckResourceAttr("data.azurerm_resource_group.test", "location", "westus2"),
|
||||||
|
resource.TestCheckResourceAttr("data.azurerm_resource_group.test", "tags.%", "1"),
|
||||||
|
resource.TestCheckResourceAttr("data.azurerm_resource_group.test", "tags.env", "test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccDataSourceAzureRMResourceGroupBasic(name string) string {
|
||||||
|
return fmt.Sprintf(`resource "azurerm_resource_group" "test" {
|
||||||
|
name = "%s"
|
||||||
|
location = "West US 2"
|
||||||
|
tags {
|
||||||
|
env = "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "azurerm_resource_group" "test" {
|
||||||
|
name = "${azurerm_resource_group.test.name}"
|
||||||
|
}
|
||||||
|
`, name)
|
||||||
|
}
|
|
@ -16,6 +16,13 @@ func locationSchema() *schema.Schema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func locationForDataSourceSchema() *schema.Schema {
|
||||||
|
return &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func deprecatedLocationSchema() *schema.Schema {
|
func deprecatedLocationSchema() *schema.Schema {
|
||||||
return &schema.Schema{
|
return &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
|
|
@ -62,8 +62,9 @@ func Provider() terraform.ResourceProvider {
|
||||||
},
|
},
|
||||||
|
|
||||||
DataSourcesMap: map[string]*schema.Resource{
|
DataSourcesMap: map[string]*schema.Resource{
|
||||||
"azurerm_client_config": dataSourceArmClientConfig(),
|
"azurerm_client_config": dataSourceArmClientConfig(),
|
||||||
"azurerm_public_ip": dataSourceArmPublicIP(),
|
"azurerm_resource_group": dataSourceArmResourceGroup(),
|
||||||
|
"azurerm_public_ip": dataSourceArmPublicIP(),
|
||||||
},
|
},
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
|
|
@ -101,6 +101,31 @@ func parseAzureResourceID(id string) (*ResourceID, error) {
|
||||||
return idObj, nil
|
return idObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func composeAzureResourceID(idObj *ResourceID) (id string, err error) {
|
||||||
|
if idObj.SubscriptionID == "" || idObj.ResourceGroup == "" {
|
||||||
|
return "", fmt.Errorf("SubscriptionID and ResourceGroup cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
id = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s", idObj.SubscriptionID, idObj.ResourceGroup)
|
||||||
|
|
||||||
|
if idObj.Provider != "" {
|
||||||
|
if len(idObj.Path) < 1 {
|
||||||
|
return "", fmt.Errorf("ResourceID.Path should have at least one item when ResourceID.Provider is specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
id += fmt.Sprintf("/providers/%s", idObj.Provider)
|
||||||
|
|
||||||
|
for k, v := range idObj.Path {
|
||||||
|
if k == "" || v == "" {
|
||||||
|
return "", fmt.Errorf("ResourceID.Path cannot contain empty strings")
|
||||||
|
}
|
||||||
|
id += fmt.Sprintf("/%s/%s", k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func parseNetworkSecurityGroupName(networkSecurityGroupId string) (string, error) {
|
func parseNetworkSecurityGroupName(networkSecurityGroupId string) (string, error) {
|
||||||
id, err := parseAzureResourceID(networkSecurityGroupId)
|
id, err := parseAzureResourceID(networkSecurityGroupId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -143,3 +143,88 @@ func TestParseAzureResourceID(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestComposeAzureResourceID(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
resourceID *ResourceID
|
||||||
|
expectedID string
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
&ResourceID{
|
||||||
|
SubscriptionID: "00000000-0000-0000-0000-000000000000",
|
||||||
|
ResourceGroup: "testGroup1",
|
||||||
|
Provider: "foo.bar",
|
||||||
|
Path: map[string]string{
|
||||||
|
"k1": "v1",
|
||||||
|
"k2": "v2",
|
||||||
|
"k3": "v3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testGroup1/providers/foo.bar/k1/v1/k2/v2/k3/v3",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
&ResourceID{
|
||||||
|
SubscriptionID: "00000000-0000-0000-0000-000000000000",
|
||||||
|
ResourceGroup: "testGroup1",
|
||||||
|
},
|
||||||
|
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testGroup1",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// If Provider is specified, there must be at least one element in Path.
|
||||||
|
&ResourceID{
|
||||||
|
SubscriptionID: "00000000-0000-0000-0000-000000000000",
|
||||||
|
ResourceGroup: "testGroup1",
|
||||||
|
Provider: "foo.bar",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// One of the keys in Path is an empty string.
|
||||||
|
&ResourceID{
|
||||||
|
SubscriptionID: "00000000-0000-0000-0000-000000000000",
|
||||||
|
ResourceGroup: "testGroup1",
|
||||||
|
Provider: "foo.bar",
|
||||||
|
Path: map[string]string{
|
||||||
|
"k2": "v2",
|
||||||
|
"": "v1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// One of the values in Path is an empty string.
|
||||||
|
&ResourceID{
|
||||||
|
SubscriptionID: "00000000-0000-0000-0000-000000000000",
|
||||||
|
ResourceGroup: "testGroup1",
|
||||||
|
Provider: "foo.bar",
|
||||||
|
Path: map[string]string{
|
||||||
|
"k1": "v1",
|
||||||
|
"k2": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
idString, err := composeAzureResourceID(test.resourceID)
|
||||||
|
|
||||||
|
if test.expectError && err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if test.expectedID != idString {
|
||||||
|
t.Fatalf("Unexpected resource ID string:\nExpected: %s\nGot: %s\n", test.expectedID, idString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,13 @@ func tagsSchema() *schema.Schema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tagsForDataSourceSchema() *schema.Schema {
|
||||||
|
return &schema.Schema{
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Computed: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func tagValueToString(v interface{}) (string, error) {
|
func tagValueToString(v interface{}) (string, error) {
|
||||||
switch value := v.(type) {
|
switch value := v.(type) {
|
||||||
case string:
|
case string:
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
layout: "azurerm"
|
||||||
|
page_title: "Azure Resource Manager: azurerm_resource_group"
|
||||||
|
sidebar_current: "docs-azurerm-datasource-resource-group"
|
||||||
|
description: |-
|
||||||
|
Get information about the specified resource group.
|
||||||
|
---
|
||||||
|
|
||||||
|
# azurerm\_resource\_group
|
||||||
|
|
||||||
|
Use this data source to access the properties of an Azure resource group.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
data "azurerm_resource_group" "test" {
|
||||||
|
name = "dsrg_test"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_managed_disk" "test" {
|
||||||
|
name = "managed_disk_name"
|
||||||
|
location = "${data.azurerm_resource_group.test.location}"
|
||||||
|
resource_group_name = "${data.azurerm_resource_group.test.name}"
|
||||||
|
storage_account_type = "Standard_LRS"
|
||||||
|
create_option = "Empty"
|
||||||
|
disk_size_gb = "1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
* `name` - (Required) Specifies the name of the resource group.
|
||||||
|
|
||||||
|
~> **NOTE:** If the specified location doesn't match the actual resource group location, an error message with the actual location value will be shown.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
* `location` - The location of the resource group.
|
||||||
|
* `tags` - A mapping of tags assigned to the resource group.
|
|
@ -17,6 +17,11 @@
|
||||||
<li<%= sidebar_current("docs-azurerm-datasource-client-config") %>>
|
<li<%= sidebar_current("docs-azurerm-datasource-client-config") %>>
|
||||||
<a href="/docs/providers/azurerm/d/client_config.html">azurerm_client_config</a>
|
<a href="/docs/providers/azurerm/d/client_config.html">azurerm_client_config</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-azurerm-datasource-resource-group") %>>
|
||||||
|
<a href="/docs/providers/azurerm/d/resource_group.html">azurerm_resource_group</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-azurerm-datasource-public-ip") %>>
|
<li<%= sidebar_current("docs-azurerm-datasource-public-ip") %>>
|
||||||
<a href="/docs/providers/azurerm/d/public_ip.html">azurerm_public_ip</a>
|
<a href="/docs/providers/azurerm/d/public_ip.html">azurerm_public_ip</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue