Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_app_configuration - add support for identity #8875

Merged
merged 15 commits into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ func resourceArmAppConfiguration() *schema.Resource {

"location": azure.SchemaLocation(),

"identity": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(appconfiguration.SystemAssigned),
}, false),
},
"principal_id": {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},

// the API changed and now returns the rg in lowercase
// revert when https://github.com/Azure/azure-sdk-for-go/issues/6606 is fixed
"resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(),
Expand Down Expand Up @@ -199,6 +224,11 @@ func resourceArmAppConfigurationCreate(d *schema.ResourceData, meta interface{})
Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
}

if _, ok := d.GetOk("identity"); ok {
appConfigIdentity := expandAppConfigurationIdentity(d.Get("identity").([]interface{}))
parameters.Identity = appConfigIdentity
}
favoretti marked this conversation as resolved.
Show resolved Hide resolved

future, err := client.Create(ctx, resourceGroup, name, parameters)
if err != nil {
return fmt.Errorf("Error creating App Configuration %q (Resource Group %q): %+v", name, resourceGroup, err)
Expand Down Expand Up @@ -239,6 +269,10 @@ func resourceArmAppConfigurationUpdate(d *schema.ResourceData, meta interface{})
Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
}

if _, ok := d.GetOk("identity"); ok {
parameters.Identity = expandAppConfigurationIdentity(d.Get("identity").([]interface{}))
}
favoretti marked this conversation as resolved.
Show resolved Hide resolved

future, err := client.Update(ctx, id.ResourceGroup, id.Name, parameters)
if err != nil {
return fmt.Errorf("Error updating App Configuration %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
Expand Down Expand Up @@ -308,6 +342,10 @@ func resourceArmAppConfigurationRead(d *schema.ResourceData, meta interface{}) e
d.Set("secondary_read_key", accessKeys.secondaryReadKey)
d.Set("secondary_write_key", accessKeys.secondaryWriteKey)

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

return tags.FlattenAndSet(d, resp.Tags)
}

Expand Down Expand Up @@ -408,3 +446,48 @@ func flattenAppConfigurationAccessKey(input appconfiguration.APIKey) []interface
},
}
}

func expandAppConfigurationIdentity(identities []interface{}) *appconfiguration.ResourceIdentity {
if len(identities) == 0 {
return &appconfiguration.ResourceIdentity{
Type: appconfiguration.None,
}
}
identity := identities[0].(map[string]interface{})
identityType := appconfiguration.IdentityType(identity["type"].(string))
return &appconfiguration.ResourceIdentity{
Type: identityType,
}
}
func flattenAppConfigurationIdentity(identity *appconfiguration.ResourceIdentity) []interface{} {
if identity == nil || identity.Type == appconfiguration.None {
return []interface{}{}
}
result := make(map[string]interface{})
result["type"] = identity.Type
if identity.PrincipalID != nil {
result["principal_id"] = *identity.PrincipalID
}
if identity.TenantID != nil {
result["tenant_id"] = *identity.TenantID
}
favoretti marked this conversation as resolved.
Show resolved Hide resolved
favoretti marked this conversation as resolved.
Show resolved Hide resolved
principalId := ""
if identity.PrincipalID != nil {
principalId = *identity.PrincipalID
}

tenantId := ""
if identity.TenantID != nil {
tenantId = *identity.TenantID
}

return []interface{}{
map[string]interface{}{
"type": string(identity.Type),
"principal_id": principalId,
"tenant_id": tenantId,
},
}

return []interface{}{result}
favoretti marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,60 @@ func TestAccAppConfigurationResource_complete(t *testing.T) {
})
}

func TestAccAppConfigurationResource_identity(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_app_configuration", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAppConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAppConfigurationResource_identity(data),
Check: resource.ComposeTestCheckFunc(
testCheckAppConfigurationExists(data.ResourceName),
),
},
data.ImportStep(),
},
})
}

func TestAccAppConfigurationResource_identityUpdated(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_app_configuration", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAppConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAppConfigurationResource_standard(data),
Check: resource.ComposeTestCheckFunc(
testCheckAppConfigurationExists(data.ResourceName),
),
},
{
Config: testAppConfigurationResource_identity(data),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(data.ResourceName, "identity.#", "1"),
resource.TestCheckResourceAttr(data.ResourceName, "identity.0.type", "SystemAssigned"),
resource.TestCheckResourceAttrSet(data.ResourceName, "identity.0.principal_id"),
resource.TestCheckResourceAttrSet(data.ResourceName, "identity.0.tenant_id"),
),
},
data.ImportStep(),
{
Config: testAppConfigurationResource_standard(data),
Check: resource.ComposeTestCheckFunc(
testCheckAppConfigurationExists(data.ResourceName),
),
},
data.ImportStep(),
},
})
}

func TestAccAppConfigurationResource_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_app_configuration", "test")

Expand Down Expand Up @@ -248,6 +302,34 @@ resource "azurerm_app_configuration" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func testAppConfigurationResource_identity(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_app_configuration" "test" {
name = "testaccappconf%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
sku = "standard"

identity {
type = "SystemAssigned"
}

tags = {
environment = "development"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func testAppConfigurationResource_completeUpdated(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
18 changes: 18 additions & 0 deletions website/docs/r/app_configuration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,18 @@ The following arguments are supported:

* `sku` - (Optional) The SKU name of the the App Configuration. Possible values are `free` and `standard`.

* `identity` - (Optional) An `identity` block as defined below.

~> **NOTE:** Azure does not allow a downgrade from `standard` to `free`.

* `tags` - (Optional) A mapping of tags to assign to the resource.

---

An `identity` block supports the following:

* `type` - (Required) Specifies the identity type of the App Configuration. At this time the only allowed value is `SystemAssigned`.

---
## Attributes Reference

Expand All @@ -59,6 +67,16 @@ The following attributes are exported:

* `secondary_write_key` - A `secondary_write_key` block as defined below containing the secondary write access key.

* `identity` - An `identity` block as defined below.

---

An `identity` block exports the following:

* `principal_id` - The ID of the Principal (Client) in Azure Active Directory.

* `tenant_id` - The ID of the Azure Active Directory Tenant.

---

A `primary_read_key` block exports the following:
Expand Down