Skip to content

Commit

Permalink
Add Identity Management to log_analytics (#1683)
Browse files Browse the repository at this point in the history
Added Identity Management support to log_analytics module.
  • Loading branch information
p3ck authored Sep 18, 2024
1 parent 2471bf4 commit 394eac4
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 10 deletions.
63 changes: 54 additions & 9 deletions plugins/modules/azure_rm_loganalyticsworkspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@
description:
- Resource location.
type: str
identity:
description:
- Identity for Azure Recovery Service Vault.
type: dict
version_added: '3.0.0'
suboptions:
type:
description:
- Type of the managed identity
choices:
- SystemAssigned
- UserAssigned
- None
default: None
type: str
user_assigned_identity:
description:
- User Assigned Managed Identity associated to this resource
required: false
type: str
sku:
description:
- The SKU of the workspace.
Expand Down Expand Up @@ -160,21 +180,26 @@
from ansible.module_utils.common.dict_transformations import _snake_to_camel, _camel_to_snake

try:
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt
from azure.core.exceptions import ResourceNotFoundError
from azure.mgmt.loganalytics.models import (Identity, UserIdentityProperties)
except ImportError:
# This is handled in azure_rm_common
pass


class AzureRMLogAnalyticsWorkspace(AzureRMModuleBase):
class AzureRMLogAnalyticsWorkspace(AzureRMModuleBaseExt):

def __init__(self):

self.module_arg_spec = dict(
resource_group=dict(type='str', required=True),
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent']),
identity=dict(
type='dict',
options=self.managed_identity_single_spec
),
location=dict(type='str'),
sku=dict(type='str', default='per_gb2018', choices=['free', 'standard', 'premium', 'unlimited', 'per_node', 'per_gb2018', 'standalone']),
retention_in_days=dict(type='int'),
Expand All @@ -191,13 +216,23 @@ def __init__(self):
self.name = None
self.state = None
self.location = None
self.identity = None
self.sku = None
self.retention_in_days = None
self.intelligence_packs = None
self.force = None
self._managed_identity = None

super(AzureRMLogAnalyticsWorkspace, self).__init__(self.module_arg_spec, supports_check_mode=True)

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

def exec_module(self, **kwargs):

for key in list(self.module_arg_spec.keys()) + ['tags']:
Expand All @@ -215,11 +250,18 @@ def exec_module(self, **kwargs):
else:
self.sku = _snake_to_camel(self.sku)
workspace = self.get_workspace()
update_identity = False
identity = None
if self.identity:
old_identity = workspace and workspace.identity.as_dict() or None
update_identity, identity = self.update_single_managed_identity(curr_identity=old_identity,
new_identity=self.identity)
if not workspace and self.state == 'present':
changed = True
workspace = self.log_analytics_models.Workspace(sku=self.log_analytics_models.WorkspaceSku(name=self.sku),
retention_in_days=self.retention_in_days,
location=self.location,
identity=identity,
tags=self.tags)
if not self.check_mode:
workspace = self.create_workspace(workspace)
Expand All @@ -230,10 +272,13 @@ def exec_module(self, **kwargs):
update_tags, results['tags'] = self.update_tags(workspace.tags)
if update_tags:
changed = True
if update_identity:
changed = True
if not self.check_mode and changed:
workspace = self.log_analytics_models.Workspace(sku=self.log_analytics_models.WorkspaceSku(name=self.sku),
retention_in_days=self.retention_in_days,
location=self.location,
identity=identity,
tags=results['tags'])
workspace = self.create_workspace(workspace)
elif workspace and self.state == 'absent':
Expand Down Expand Up @@ -268,7 +313,7 @@ def create_workspace(self, workspace):
poller = self.log_analytics_client.workspaces.begin_create_or_update(self.resource_group, self.name, workspace)
return self.get_poller_result(poller)
except Exception as exc:
self.fail('Error when creating workspace {0} - {1}'.format(self.name, exc.message or str(exc)))
self.fail('Error when creating workspace {0} - {1}'.format(self.name, str(exc)))

def get_workspace(self):
try:
Expand All @@ -280,7 +325,7 @@ def delete_workspace(self):
try:
self.log_analytics_client.workspaces.begin_delete(self.resource_group, self.name, force=self.force)
except Exception as exc:
self.fail('Error when deleting workspace {0} - {1}'.format(self.name, exc.message or str(exc)))
self.fail('Error when deleting workspace {0} - {1}'.format(self.name, str(exc)))

def to_dict(self, workspace):
result = workspace.as_dict()
Expand All @@ -292,7 +337,7 @@ def list_intelligence_packs(self):
response = self.log_analytics_client.intelligence_packs.list(self.resource_group, self.name)
return [x.as_dict() for x in response]
except Exception as exc:
self.fail('Error when listing intelligence packs {0}'.format(exc.message or str(exc)))
self.fail('Error when listing intelligence packs {0}'.format(str(exc)))

def change_intelligence(self, key, value):
try:
Expand All @@ -301,7 +346,7 @@ def change_intelligence(self, key, value):
else:
self.log_analytics_client.intelligence_packs.disable(self.resource_group, self.name, key)
except Exception as exc:
self.fail('Error when changing intelligence pack {0} - {1}'.format(key, exc.message or str(exc)))
self.fail('Error when changing intelligence pack {0} - {1}'.format(key, str(exc)))

def list_management_groups(self):
result = []
Expand All @@ -312,7 +357,7 @@ def list_management_groups(self):
except StopIteration:
pass
except Exception as exc:
self.fail('Error when listing management groups {0}'.format(exc.message or str(exc)))
self.fail('Error when listing management groups {0}'.format(str(exc)))
return result

def list_usages(self):
Expand All @@ -324,14 +369,14 @@ def list_usages(self):
except StopIteration:
pass
except Exception as exc:
self.fail('Error when listing usages {0}'.format(exc.message or str(exc)))
self.fail('Error when listing usages {0}'.format(str(exc)))
return result

def get_shared_keys(self):
try:
return self.log_analytics_client.shared_keys.get_shared_keys(self.resource_group, self.name).as_dict()
except Exception as exc:
self.fail('Error when getting shared key {0}'.format(exc.message or str(exc)))
self.fail('Error when getting shared key {0}'.format(str(exc)))


def main():
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ azure-mgmt-keyvault==10.0.0
azure-mgmt-cosmosdb==10.0.0b3
azure-mgmt-hdinsight==9.0.0
azure-mgmt-devtestlabs==9.0.0
azure-mgmt-loganalytics==12.0.0
azure-mgmt-loganalytics==13.0.0b6
azure-mgmt-automation==1.0.0
azure-mgmt-iothub==3.0.0
azure-iot-hub==2.6.1;platform_machine=="x86_64"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
- name: Gather Resource Group info
azure.azcollection.azure_rm_resourcegroup_info:
name: "{{ resource_group }}"
register: __rg_info

- name: Prepare random number
ansible.builtin.set_fact:
name_rpfx: "loganalytics{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
retention_days: 60
location: "{{ __rg_info.resourcegroups.0.location }}"

- name: Create User Managed Identities
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ item }}"
api_version: "2023-01-31"
body:
location: "{{ location }}"
state: present
loop:
- "ansible-test-loganalyze-identity"

- name: Set identities IDs to test. Identities ansible-test-loganalyze-identity have to be created previously
ansible.builtin.set_fact:
user_identity_1: "/subscriptions/{{ azure_subscription_id }}/resourcegroups/{{ resource_group }}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ansible-test-loganalyze-identity"

- name: Create Log Analytics Workspace (Check Mode On)
azure_rm_loganalyticsworkspace:
Expand All @@ -11,6 +34,8 @@
Containers: true
retention_in_days: "{{ retention_days }}"
resource_group: "{{ resource_group }}"
identity:
type: SystemAssigned
check_mode: true
register: output

Expand Down Expand Up @@ -44,6 +69,8 @@
resource_group: "{{ resource_group }}"
tags:
key1: value1
identity:
type: SystemAssigned
register: output

- name: Assert the log analytics workspace created
Expand All @@ -55,6 +82,7 @@
# - output.intelligence_packs | json_query('[?name == `Containers`].enabled') | first == true
- output.sku == 'per_gb2018'
- output.tags.key1 == 'value1'
- output.identity.type == 'SystemAssigned'

- name: Update Log Analytics Workspace
azure_rm_loganalyticsworkspace:
Expand All @@ -67,6 +95,9 @@
tags:
key1: value1
key2: value2
identity:
type: UserAssigned
user_assigned_identity: "{{ user_identity_1 }}"
register: output

- name: Assert the log analytics workspace updated
Expand All @@ -75,6 +106,8 @@
- output.changed
- output.retention_in_days == retention_days
- output.tags.key2 == 'value2'
- output.identity.type == 'UserAssigned'
- output.identity.user_assigned_identities | length == 1

- name: Get Log Analytics workspace information (Show full information)
azure_rm_loganalyticsworkspace_info:
Expand Down Expand Up @@ -102,6 +135,7 @@
- facts.workspaces[0].usages | length > 0
- facts.workspaces[0].management_groups is defined
- facts.workspaces[0].sku == 'per_gb2018'
- user_identity_1 in facts.workspaces[0].identity.user_assigned_identities

- name: Get Log Analytics workspace information (Show default information)
azure_rm_loganalyticsworkspace_info:
Expand Down Expand Up @@ -193,3 +227,14 @@
ansible.builtin.assert:
that:
- not output.changed

- name: Destroy User Managed Identities
azure_rm_resource:
resource_group: "{{ resource_group }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ item }}"
api_version: "2023-01-31"
state: absent
loop:
- "ansible-test-loganalyze-identity"

0 comments on commit 394eac4

Please sign in to comment.