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

Support for System and User Assigned Managed Identities in azurerm_eventgrid_domain, azurerm_eventgrid_topic and azurerm_eventgrid_system_topic #12951

Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
93fd90c
r/eventgrid_topic: managed identity
jrauschenbusch Dec 8, 2020
c9ab575
fixes
jrauschenbusch Dec 8, 2020
39f6ab1
identity acc tests
jrauschenbusch Dec 17, 2020
390f87d
add identity to eventgrid domain
jrauschenbusch Dec 17, 2020
6addeb5
docs
jrauschenbusch Dec 17, 2020
1620814
fix: check if input is nil
jrauschenbusch Aug 11, 2021
10cf9be
fix: documentation
jrauschenbusch Aug 11, 2021
3105b2f
fix: add tests for identity_ids
jrauschenbusch Aug 11, 2021
d6ebf28
fix: PR notes
jrauschenbusch Aug 11, 2021
48ecb5c
fix: refactor identity assignment
jrauschenbusch Aug 11, 2021
3ca99ec
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
e9a772a
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
0949257
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
d3b873e
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
e1501c9
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
d24da41
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
e7341b4
Update website/docs/r/eventgrid_topic.html.markdown
jrauschenbusch Sep 3, 2021
5b7e378
Merge branch 'main' into event-grid-topic-system-managed-identity
jrauschenbusch Sep 4, 2021
5d003a6
fix: rename conflicting identity functions
jrauschenbusch Sep 6, 2021
11ba381
fix: update tests to use acceptance module
jrauschenbusch Sep 6, 2021
02d4dc1
feat: added identity support to system topic
jrauschenbusch Sep 6, 2021
e9e8977
fix: system topic tests
jrauschenbusch Sep 6, 2021
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
110 changes: 107 additions & 3 deletions internal/services/eventgrid/eventgrid.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,57 @@
package eventgrid

import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2020-10-15-preview/eventgrid"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func eventSubscriptionPublicNetworkAccessEnabled() *pluginsdk.Schema {
return &pluginsdk.Schema{
Type: pluginsdk.TypeBool,
func IdentitySchema() *schema.Schema {
return &schema.Schema{
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(eventgrid.IdentityTypeNone),
string(eventgrid.IdentityTypeSystemAssigned),
string(eventgrid.IdentityTypeUserAssigned),
}, false),
},

"identity_ids": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},

"principal_id": {
Type: schema.TypeString,
Computed: true,
},

"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
}
}

func eventSubscriptionPublicNetworkAccessEnabled() *schema.Schema {
return &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
}
Expand Down Expand Up @@ -93,3 +135,65 @@ func flattenInboundIPRules(in *[]eventgrid.InboundIPRule) []interface{} {
}
return rules
}

func expandIdentity(input []interface{}) (*eventgrid.IdentityInfo, error) {
if len(input) == 0 || input[0] == nil {
return &eventgrid.IdentityInfo{
Type: eventgrid.IdentityTypeNone,
}, nil
}

raw := input[0].(map[string]interface{})

identity := eventgrid.IdentityInfo{
Type: eventgrid.IdentityType(raw["type"].(string)),
}

identityIdsRaw := raw["identity_ids"].(*schema.Set).List()
identityIds := make(map[string]*eventgrid.UserIdentityProperties)
for _, v := range identityIdsRaw {
identityIds[v.(string)] = &eventgrid.UserIdentityProperties{}
}

if len(identityIds) > 0 {
if identity.Type != eventgrid.IdentityTypeUserAssigned && identity.Type != eventgrid.IdentityTypeSystemAssignedUserAssigned {
return nil, fmt.Errorf("`identity_ids` can only be specified when `type` includes `UserAssigned`")
}

identity.UserAssignedIdentities = identityIds
}

return &identity, nil
}

func flattenIdentity(input *eventgrid.IdentityInfo) []interface{} {
if input == nil || input.Type == eventgrid.IdentityTypeNone {
return []interface{}{}
}

identityIds := make([]string, 0)
if input.UserAssignedIdentities != nil {
for k := range input.UserAssignedIdentities {
identityIds = append(identityIds, k)
}
}

principalID := ""
if input.PrincipalID != nil {
principalID = *input.PrincipalID
}

tenantID := ""
if input.TenantID != nil {
tenantID = *input.TenantID
}

return []interface{}{
map[string]interface{}{
"type": string(input.Type),
"identity_ids": identityIds,
"principal_id": principalID,
"tenant_id": tenantID,
},
}
}
18 changes: 17 additions & 1 deletion internal/services/eventgrid/eventgrid_domain_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func resourceEventGridDomain() *pluginsdk.Resource {

"resource_group_name": azure.SchemaResourceGroupName(),

"tags": tags.Schema(),
"identity": IdentitySchema(),

"input_schema": {
Type: pluginsdk.TypeString,
Expand Down Expand Up @@ -158,6 +158,8 @@ func resourceEventGridDomain() *pluginsdk.Resource {
Computed: true,
Sensitive: true,
},

"tags": tags.Schema(),
},
}
}
Expand Down Expand Up @@ -199,6 +201,15 @@ func resourceEventGridDomainCreateUpdate(d *pluginsdk.ResourceData, meta interfa
Tags: tags.Expand(t),
}

if v, ok := d.GetOk("identity"); ok {
identityRaw := v.([]interface{})
identity, err := expandIdentity(identityRaw)
if err != nil {
return fmt.Errorf("expanding `identity`: %+v", err)
}
domain.Identity = identity
}

log.Printf("[INFO] preparing arguments for AzureRM EventGrid Domain creation with Properties: %+v", domain)

future, err := client.CreateOrUpdate(ctx, resourceGroup, name, domain)
Expand Down Expand Up @@ -286,6 +297,11 @@ func resourceEventGridDomainRead(d *pluginsdk.ResourceData, meta interface{}) er
if err != nil {
return fmt.Errorf("retrieving Shared Access Keys for EventGrid Domain %q: %+v", id.Name, err)
}

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

d.Set("primary_access_key", keys.Key1)
d.Set("secondary_access_key", keys.Key2)

Expand Down
100 changes: 98 additions & 2 deletions internal/services/eventgrid/eventgrid_domain_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/eventgrid/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

Expand Down Expand Up @@ -108,7 +109,47 @@ func TestAccEventGridDomain_inboundIPRules(t *testing.T) {
})
}

func (EventGridDomainResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
func TestAccEventGridDomain_basicWithSystemManagedIdentity(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_eventgrid_domain", "test")
r := EventGridDomainResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basicWithSystemManagedIdentity(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("identity.#").HasValue("1"),
check.That(data.ResourceName).Key("identity.0.type").HasValue("SystemAssigned"),
check.That(data.ResourceName).Key("identity.0.identity_ids.#").HasValue("0"),
check.That(data.ResourceName).Key("identity.0.principal_id").Exists(),
check.That(data.ResourceName).Key("identity.0.tenant_id").Exists(),
),
},
data.ImportStep(),
})
}

func TestAccEventGridDomain_basicWithUserAssignedManagedIdentity(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_eventgrid_domain", "test")
r := EventGridDomainResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basicWithUserAssignedManagedIdentity(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("identity.#").HasValue("1"),
check.That(data.ResourceName).Key("identity.0.type").HasValue("UserAssigned"),
check.That(data.ResourceName).Key("identity.0.identity_ids.#").HasValue("1"),
check.That(data.ResourceName).Key("identity.0.principal_id").IsEmpty(),
check.That(data.ResourceName).Key("identity.0.tenant_id").IsEmpty(),
),
},
data.ImportStep(),
})
}

func (EventGridDomainResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) {
id, err := parse.DomainID(state.ID)
if err != nil {
return nil, err
Expand Down Expand Up @@ -238,3 +279,58 @@ resource "azurerm_eventgrid_domain" "test" {
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

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

resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}

resource "azurerm_eventgrid_domain" "test" {
name = "acctesteg-%[1]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name

identity {
type = "SystemAssigned"
}
}
`, data.RandomInteger, data.Locations.Primary)
}

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

resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}

resource "azurerm_user_assigned_identity" "test" {
name = "acctesteg-%[1]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
}

resource "azurerm_eventgrid_domain" "test" {
name = "acctesteg-%[1]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name

identity {
type = "UserAssigned"
identity_ids = [
azurerm_user_assigned_identity.test.id
]
}
}
`, data.RandomInteger, data.Locations.Primary)
}
21 changes: 18 additions & 3 deletions internal/services/eventgrid/eventgrid_topic_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ func resourceEventGridTopic() *pluginsdk.Resource {

"resource_group_name": azure.SchemaResourceGroupName(),

"identity": IdentitySchema(),

"input_schema": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -193,15 +195,24 @@ func resourceEventGridTopicCreateUpdate(d *pluginsdk.ResourceData, meta interfac
InboundIPRules: expandInboundIPRules(d),
}

properties := eventgrid.Topic{
topic := eventgrid.Topic{
Location: &location,
TopicProperties: topicProperties,
Tags: tags.Expand(t),
}

log.Printf("[INFO] preparing arguments for AzureRM EventGrid Topic creation with Properties: %+v.", properties)
if v, ok := d.GetOk("identity"); ok {
identityRaw := v.([]interface{})
identity, err := expandIdentity(identityRaw)
if err != nil {
return fmt.Errorf("expanding `identity`: %+v", err)
}
topic.Identity = identity
}

future, err := client.CreateOrUpdate(ctx, resourceGroup, name, properties)
log.Printf("[INFO] preparing arguments for AzureRM EventGrid Topic creation with Properties: %+v.", topic)

future, err := client.CreateOrUpdate(ctx, resourceGroup, name, topic)
if err != nil {
return err
}
Expand Down Expand Up @@ -290,6 +301,10 @@ func resourceEventGridTopicRead(d *pluginsdk.ResourceData, meta interface{}) err
d.Set("endpoint", props.Endpoint)
}

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

d.Set("primary_access_key", keys.Key1)
d.Set("secondary_access_key", keys.Key2)

Expand Down
Loading