Skip to content

Commit

Permalink
Add support for Managed User Identities to sqlManagedInstance (ansibl…
Browse files Browse the repository at this point in the history
  • Loading branch information
p3ck authored and Justwmz committed Nov 4, 2024
1 parent fdf9e78 commit 4180c2a
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 26 deletions.
82 changes: 62 additions & 20 deletions plugins/modules/azure_rm_sqlmanagedinstance.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,30 @@
- Azure Active Directory identity configuration for a resource.
type: dict
suboptions:
user_assigned_identities:
description:
- The resource ids of the user assigned identities to use.
type: str
principal_id:
description:
- The Azure Active Directory principal ID.
type: str
type:
description:
- The identity type.
- Set this to C(SystemAssigned) in order to automatically create and assign an Azure Active Directory principal for the resource.
- Type of the managed identity
choices:
- SystemAssigned
- UserAssigned
- SystemAssigned, UserAssigned
- None
default: None
type: str
tenant_id:
user_assigned_identities:
description:
- The Azure Active Directory tenant id.
type: str
- User Assigned Managed Identities and its options
required: false
type: dict
default: {}
suboptions:
id:
description:
- List of the user assigned identities IDs associated to the WebApp
required: false
type: list
elements: str
default: []
managed_instance_create_mode:
description:
- Specifies the mode of database creation.
Expand Down Expand Up @@ -513,6 +520,7 @@

try:
from azure.core.exceptions import ResourceNotFoundError
from azure.mgmt.sql.models import (ResourceIdentity, UserIdentity)
except ImportError:
pass

Expand All @@ -526,11 +534,28 @@
)


identity_spec = dict(
user_assigned_identities=dict(type='str'),
principal_id=dict(type='str'),
type=dict(type='str'),
tenant_id=dict(type='str')
user_assigned_identities_spec = dict(
id=dict(
type='list',
default=[],
elements='str'
)
)

managed_identity_spec = dict(
type=dict(
type='str',
choices=['SystemAssigned',
'UserAssigned',
'SystemAssigned, UserAssigned',
'None'],
default='None'
),
user_assigned_identities=dict(
type='dict',
options=user_assigned_identities_spec,
default={}
),
)


Expand All @@ -555,7 +580,7 @@ def __init__(self):
),
identity=dict(
type='dict',
options=identity_spec
options=managed_identity_spec
),
sku=dict(
type='dict',
Expand Down Expand Up @@ -648,10 +673,20 @@ def __init__(self):
self.name = None
self.location = None
self.state = None
self.identity = None
self.body = dict()
self._managed_identity = None

super(AzureRMSqlManagedInstance, self).__init__(self.module_arg_spec, supports_check_mode=True, supports_tags=True)

@property
def managed_identity(self):
if not self._managed_identity:
self._managed_identity = {"identity": ResourceIdentity,
"user_assigned": UserIdentity
}
return self._managed_identity

def exec_module(self, **kwargs):

for key in list(self.module_arg_spec) + ['tags']:
Expand All @@ -668,6 +703,13 @@ def exec_module(self, **kwargs):
self.body['location'] = self.location

sql_managed_instance = self.get()

update_identity, identity = self.update_managed_identity(sql_managed_instance and
sql_managed_instance.get('identity'),
self.identity)
if update_identity:
self.body["identity"] = identity.as_dict()

changed = False
if self.state == 'present':
if sql_managed_instance:
Expand All @@ -678,7 +720,7 @@ def exec_module(self, **kwargs):
if not self.default_compare(modifiers, self.body, sql_managed_instance, '', self.results):
changed = True

if changed:
if changed or update_identity:
if not self.check_mode:
# sql_managed_instance = self.update_sql_managed_instance(self.body)
sql_managed_instance = self.create_or_update(self.body)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
- name: Prepare random number
- name: Gather Resource Group info
azure.azcollection.azure_rm_resourcegroup_info:
name: "{{ resource_group }}"
register: __rg_info

- name: Prepare random number and set location based on resource group
ansible.builtin.set_fact:
random_postfix: "sqlmi{{ 1000 | random }}{{ resource_group | hash('md5') | truncate(7, True, '') }}"
password: "{{ lookup('ansible.builtin.password', '/dev/null', chars=['ascii_letters', 'digits', 'punctuation'], length=25) }}"
location: "{{ __rg_info.resourcegroups.0.location }}"

- name: Delete sql managed instance
azure_rm_sqlmanagedinstance:
resource_group: "{{ resource_group }}"
name: "{{ random_postfix }}"
state: absent

- name: Create identity and policy ids arrays
ansible.builtin.set_fact:
managed_identity_ids: []
access_policies_object_ids: []

- name: Create user managed identities
ansible.builtin.include_tasks: managedidentity.yml
vars:
managed_identity_test_unique: 'sqlmanagedinstance'
managed_identity_unique: "{{ item }}"
managed_identity_action: 'create'
managed_identity_location: "{{ location }}"
with_items:
- '1'
- '2'

- name: Create virtual network
azure_rm_virtualnetwork:
Expand Down Expand Up @@ -69,7 +97,11 @@
name: "{{ random_postfix }}"
subnet_id: "{{ subnet_output.state.id }}"
identity:
type: SystemAssigned
type: UserAssigned
user_assigned_identities:
id:
- "{{ managed_identity_ids[0] }}"
primary_user_assigned_identity_id: "{{ managed_identity_ids[0] }}"
sku:
name: GP_Gen5
tier: GeneralPurpose
Expand All @@ -81,6 +113,7 @@
v_cores: 8
tags:
key0: value0
check_mode: true
register: output

- name: Assert the resource instance is not exist
Expand All @@ -94,7 +127,11 @@
name: "{{ random_postfix }}"
subnet_id: "{{ subnet_output.state.id }}"
identity:
type: SystemAssigned
type: UserAssigned
user_assigned_identities:
id:
- "{{ managed_identity_ids[0] }}"
primary_user_assigned_identity_id: "{{ managed_identity_ids[0] }}"
sku:
name: GP_Gen5
tier: GeneralPurpose
Expand All @@ -113,13 +150,26 @@
that:
- output.changed

- name: Wait for sql managed instance provisioning to complete
azure_rm_sqlmanagedinstance_info:
resource_group: "{{ resource_group }}"
name: "{{ random_postfix }}"
register: facts
until: facts.sql_managed_instance[0]['state'] == 'Ready'
retries: 40
delay: 60

- name: Create sql managed instance (Idempotent test)
azure_rm_sqlmanagedinstance:
resource_group: "{{ resource_group }}"
name: "{{ random_postfix }}"
subnet_id: "{{ subnet_output.state.id }}"
identity:
type: SystemAssigned
type: UserAssigned
user_assigned_identities:
id:
- "{{ managed_identity_ids[0] }}"
primary_user_assigned_identity_id: "{{ managed_identity_ids[0] }}"
sku:
name: GP_Gen5
tier: GeneralPurpose
Expand All @@ -137,13 +187,17 @@
that:
- not output.changed

- name: Upgarde sql managed instance with tags
- name: Upgrade sql managed instance with tags
azure_rm_sqlmanagedinstance:
resource_group: "{{ resource_group }}"
name: "{{ random_postfix }}"
subnet_id: "{{ subnet_output.state.id }}"
identity:
type: SystemAssigned
type: UserAssigned
user_assigned_identities:
id:
- "{{ managed_identity_ids[0] }}"
primary_user_assigned_identity_id: "{{ managed_identity_ids[0] }}"
sku:
name: GP_Gen5
tier: GeneralPurpose
Expand Down Expand Up @@ -175,9 +229,32 @@
- output.sql_managed_instance[0].tags | length == 1
- output.sql_managed_instance[0].storage_size_in_gb == 256
- output.sql_managed_instance[0].sku.name == 'GP_Gen5'
- output.sql_managed_instance[0].identity.type == 'UserAssigned'
- output.sql_managed_instance[0].identity.user_assigned_identities | length == 1
- output.sql_managed_instance[0].identity.user_assigned_identities[managed_identity_ids[0]] is defined

- name: Wait for sql managed instance provisioning to complete
azure_rm_sqlmanagedinstance_info:
resource_group: "{{ resource_group }}"
name: "{{ random_postfix }}"
register: facts
until: facts.sql_managed_instance[0]['state'] == 'Ready'
retries: 40
delay: 60

- name: Delete sql managed instance
azure_rm_sqlmanagedinstance:
resource_group: "{{ resource_group }}"
name: "{{ random_postfix }}"
state: absent

- name: Delete user managed identities
ansible.builtin.include_tasks: managedidentity.yml
vars:
managed_identity_test_unique: 'sqlmanagedinstance'
managed_identity_unique: "{{ item }}"
managed_identity_action: 'delete'
managed_identity_location: "{{ location }}"
with_items:
- '1'
- '2'
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
- name: Set user managed identity name
ansible.builtin.set_fact:
identity_name: "ansible-test-{{ managed_identity_test_unique }}-identity-{{ managed_identity_unique }}"

- name: Set user managed identity ID base path
ansible.builtin.set_fact:
base_path: "/subscriptions/{{ azure_subscription_id }}/resourcegroups/{{ resource_group }}"

- name: Set user managed identity ID
ansible.builtin.set_fact:
identity_id: "{{ base_path }}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{{ identity_name }}"

- name: Set managed identity ID into the ids list.
ansible.builtin.set_fact:
managed_identity_ids: "{{ managed_identity_ids + [identity_id] }}"
when: managed_identity_action == 'create'

- name: Create the user managed identity - {{ identity_name }}
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ identity_name }}"
api_version: "2023-01-31"
body:
location: "{{ managed_identity_location }}"
state: present
when: managed_identity_action == 'create'

- name: Lookup service principal object id for identity {{ identity_name }}
azure_rm_resource_info:
api_version: "2023-01-31"
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ identity_name }}"
register: output
when:
- access_policies_object_ids is defined
- managed_identity_action == 'create'

- name: Set object ID for identity {{ identity_name }}
ansible.builtin.set_fact:
access_policies_object_ids: "{{ access_policies_object_ids + [output.response[0].properties.principalId] }}"
when:
- access_policies_object_ids is defined
- managed_identity_action == 'create'

- name: Destroy the user managed identity - {{ identity_name }}
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ identity_name }}"
api_version: "2023-01-31"
state: absent
when: managed_identity_action == 'delete'

0 comments on commit 4180c2a

Please sign in to comment.