-
Notifications
You must be signed in to change notification settings - Fork 26
/
setup_azure_authz.yml
210 lines (190 loc) · 11.2 KB
/
setup_azure_authz.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
---
# Copyright 2021 Cloudera, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- name: Handle Azure Cross Account Role
register: __azure_xaccount_role_info
azure.azcollection.azure_rm_roledefinition: # This version fails idempotence if a description is set
state: present
name: "{{ plat__azure_xaccount_role_name }}"
assignable_scopes: "/subscriptions/{{ plat__azure_subscription_id }}"
permissions:
- actions: "{{ lookup('file', __azure_policy_document.dest ) | from_json | community.general.json_query('Actions') }}"
data_actions: "{{ lookup('file', __azure_policy_document.dest ) | from_json | community.general.json_query('DataActions') }}"
not_actions: "{{ lookup('file', __azure_policy_document.dest ) | from_json | community.general.json_query('NotActions') }}"
not_data_actions: "{{ lookup('file', __azure_policy_document.dest ) | from_json | community.general.json_query('NotDataActions') }}"
- name: Ensure Azure Cross Account App and Credential are Deployed
when: plat__azure_xaccount_app_uuid is undefined or plat__xacccount_credential_name not in plat__cdp_credentials_list
block:
- name: Remove CDP Cross Account Credential for Recreation as Azure App needs (re)creating
cloudera.cloud.env_cred:
state: absent
name: "{{ plat__xacccount_credential_name }}"
# Azure xaccount App and Credential must be created in the same session, or already exist
- name: Remove Azure App as CDP Credential needs (re)creating
when: plat__azure_xaccount_app_uuid is defined
block:
- name: Issue Azure App Delete command
command: "az ad app delete --id {{ plat__azure_xaccount_app_uuid }}"
- name: Wait for consistency
ansible.builtin.pause:
seconds: "{{ plat__azure_consistency_wait }}"
- name: Request Azure Cross Account App Creation
no_log: True
register: __azure_xaccount_app_info
command: >
az ad sp create-for-rbac
--name {{ plat__azure_xaccount_app_name }}
--role {{ plat__azure_xaccount_use_custom_role | ternary(__azure_xaccount_role_info.id, plat__azure_roles.contrib) }}
--scope {{ plat__azure_xaccount_rg_scope | ternary(plat__azure_metagroup_uri, plat__azure_subscription_uri) }}
- name: Register Azure Cross Account App info
no_log: True
ansible.builtin.set_fact:
__azure_xaccount_app_pword: "{{ __azure_xaccount_app_info.stdout | from_json | community.general.json_query('password') }}"
plat__azure_xaccount_app_uuid: "{{ __azure_xaccount_app_info.stdout | from_json | community.general.json_query('appId') }}"
- name: Validate that the Azure Cross Account App info has been set
no_log: True
ansible.builtin.assert:
quiet: yes
that:
- __azure_xaccount_app_pword | length > 0
- plat__azure_xaccount_app_uuid | length > 0
fail_msg: "Did not retrieve Cross Account App UUID and Password from creation, please try again"
success_msg: "Azure Cross Account App UUID and Password appear to have been extracted"
- name: Wait for consistency
ansible.builtin.pause:
seconds: "{{ plat__azure_consistency_wait }}"
- name: Refresh listing of Azure Service Principals
ansible.builtin.command: "az ad sp list --filter {{ __azure_ad_filter | quote }}"
vars:
__azure_ad_filter: "appId eq '{{ plat__azure_xaccount_app_uuid }}'"
register: __azure_application_service_principals_list
- name: Check that we found a valid Service Principal for the Azure App
ansible.builtin.assert:
quiet: yes
that: __azure_application_service_principals_list.stdout | from_json | length == 1
fail_msg: "Expected exactly one result from Azure Service Principal query for UUID {{ plat__azure_xaccount_app_uuid}}, got {{ __azure_application_service_principals_list.stdout | from_json | length }} instead"
success_msg: "Found New Azure Cross Account App in directory matching UUID {{ plat__azure_xaccount_app_uuid }}, using for Cross Account Credential Creation"
- name: Set Service Principal Object ID for new Azure App
ansible.builtin.set_fact:
plat__azure_application_service_principal_objuuid: "{{ __azure_application_service_principals_list.stdout | from_json | community.general.json_query('[0].id') }}"
- name: Check that Azure Service Principal ID is now set
ansible.builtin.assert:
quiet: yes
that: plat__azure_application_service_principal_objuuid | length > 0
fail_msg: "Azure Service Principal Object ID appears to be length 0, please check and try again"
- name: Create the CDP Cross Account Credential with the new Azure App details
cloudera.cloud.env_cred:
state: present
cloud: "{{ plat__infra_type }}"
name: "{{ plat__xacccount_credential_name }}"
subscription: "{{ plat__azure_subscription_id }}"
tenant: "{{ plat__azure_tenant_id }}"
application: "{{ plat__azure_xaccount_app_uuid }}"
secret: "{{ __azure_xaccount_app_pword }}"
- name: Request creation of Azure Managed Identities
loop_control:
loop_var: __azure_msi_item
register: __azure_az_msi_info
azure.azcollection.azure_rm_resource:
resource_group: "{{ plat__azure_metagroup_name }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
resource_name: "{{ __azure_msi_item }}"
api_version: '2018-11-30'
idempotency: yes
state: present
body:
location: "{{ plat__region }}"
loop:
- "{{ plat__azure_idbroker_identity_name }}"
- "{{ plat__azure_datalakeadmin_identity_name }}"
- "{{ plat__azure_log_identity_name }}"
- "{{ plat__azure_ranger_audit_identity_name }}"
- name: Wait for MSIs to be listed
azure.azcollection.azure_rm_resource_info:
resource_group: "{{ plat__azure_metagroup_name }}"
provider: ManagedIdentity
resource_type: userAssignedIdentities
api_version: '2018-11-30'
register: __azure_identity_list
delay: 5
retries: 120 # 10 mins
until:
- plat__azure_idbroker_identity_name in discovered_msi_list
- plat__azure_datalakeadmin_identity_name in discovered_msi_list
- plat__azure_log_identity_name in discovered_msi_list
- plat__azure_ranger_audit_identity_name in discovered_msi_list
vars:
discovered_msi_list: "{{ __azure_identity_list.response | map(attribute='name') | list }}"
- name: Extract Azure Identity Principals
ansible.builtin.set_fact:
__azure_idbroker_identity: "{{ __azure_identity_list.response | selectattr('name', 'eq', plat__azure_idbroker_identity_name) | first }}"
__azure_datalakeadmin_identity: "{{ __azure_identity_list.response | selectattr('name', 'eq', plat__azure_datalakeadmin_identity_name) | first }}"
__azure_log_identity: "{{ __azure_identity_list.response | selectattr('name', 'eq', plat__azure_log_identity_name) | first }}"
__azure_ranger_audit_identity: "{{ __azure_identity_list.response | selectattr('name', 'eq', plat__azure_ranger_audit_identity_name) | first }}"
- name: Refresh listing of Azure Role Definitions
register: __azure_role_definition_info
no_log: yes # Extremely verbose output
azure.azcollection.azure_rm_roledefinition_info:
scope: "{{ plat__azure_subscription_uri }}"
- name: Extract Azure Role Definition IDs
ansible.builtin.set_fact:
__azure_xaccount_role_id: "{{ __azure_role_definition_info.roledefinitions | selectattr('role_name', 'eq', plat__azure_xaccount_role_name) | map(attribute='id') | list | first }}"
__azure_virtualmachine_ctrb_role_id: "{{ __azure_role_definition_info.roledefinitions | selectattr('role_name', 'eq', plat__azure_roles.vmcnt) | map(attribute='id') | list | first }}"
__azure_managedidentity_optr_role_id: "{{ __azure_role_definition_info.roledefinitions | selectattr('role_name', 'eq', plat__azure_roles.miop) | map(attribute='id') | list | first }}"
__azure_storageblobdata_ownr_role_id: "{{ __azure_role_definition_info.roledefinitions | selectattr('role_name', 'eq', plat__azure_roles.storown) | map(attribute='id') | list | first }}"
__azure_storageblobdata_ctrb_role_id: "{{ __azure_role_definition_info.roledefinitions | selectattr('role_name', 'eq', plat__azure_roles.storcnt) | map(attribute='id') | list | first }}"
__azure_contributor_role_id: "{{ __azure_role_definition_info.roledefinitions | selectattr('role_name', 'eq', plat__azure_roles.contrib) | map(attribute='id') | list | first }}"
- name: Process Azure Role Assignments
register: __infra_az_sp_assign_result
until: __infra_az_sp_assign_result is not failed
retries: 3
delay: 3
azure.azcollection.azure_rm_roleassignment:
state: present
scope: "{{ __azure_rl_assgn_item.scope }}"
assignee_object_id: "{{ __azure_rl_assgn_item.assignee }}"
role_definition_id: "{{ __azure_rl_assgn_item.role }}"
loop:
- role: "{{ __azure_virtualmachine_ctrb_role_id }}"
scope: "{{ plat__azure_subscription_uri }}"
assignee: "{{ __azure_idbroker_identity.properties.principalId }}"
desc: Assign VM Contributor Role to IDBroker Identity at Subscription Level
- role: "{{ __azure_managedidentity_optr_role_id }}"
scope: "{{ plat__azure_subscription_uri }}"
assignee: "{{ __azure_idbroker_identity.properties.principalId }}"
desc: Assign Managed Identity Operator Role to IDBroker Identity at Subscription Level
- role: "{{ __azure_storageblobdata_ownr_role_id }}"
scope: "{{ plat__azure_logpath_uri }}"
assignee: "{{ __azure_datalakeadmin_identity.properties.principalId }}"
desc: Assign Storage Blob Data Owner Role to Data Lake Admin Identity at Logs Container Level
- role: "{{ __azure_storageblobdata_ownr_role_id }}"
scope: "{{ plat__azure_datapath_uri }}"
assignee: "{{ __azure_datalakeadmin_identity.properties.principalId }}"
desc: Assign Storage Blob Data Owner Role to Data Lake Admin Identity at Data Container Level
- role: "{{ __azure_storageblobdata_ctrb_role_id }}"
scope: "{{ plat__azure_logpath_uri }}"
assignee: "{{ __azure_log_identity.properties.principalId }}"
desc: Assign Storage Blob Data Contributor Role to Log Role at Logs Container level
- role: "{{ __azure_storageblobdata_ctrb_role_id }}"
scope: "{{ plat__azure_datapath_uri }}"
assignee: "{{ __azure_ranger_audit_identity.properties.principalId }}"
desc: Assign Storage Blob Data Contributor Role to Ranger Audit Role at Data Container level
loop_control:
loop_var: __azure_rl_assgn_item
label: "{{ __azure_rl_assgn_item.desc }}"
failed_when:
- "'rc' in __infra_az_sp_assign_result"
- __infra_az_sp_assign_result.rc != 0
- "'The role assignment already exists' not in __infra_az_sp_assign_result.module_stderr"