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

azure_rm_roleassignment fails when the role assignment already exists #145

Closed
wrprice opened this issue Jun 4, 2020 · 7 comments · Fixed by #301
Closed

azure_rm_roleassignment fails when the role assignment already exists #145

wrprice opened this issue Jun 4, 2020 · 7 comments · Fixed by #301
Labels
high_priority High priority

Comments

@wrprice
Copy link

wrprice commented Jun 4, 2020

Migrating from ansible/ansible#67529 unrequested but on behalf of @adhodgson1. The details below are copied from that report.

SUMMARY

The azure_rm_roleassignment module runs in a playbook fine the first time but on subsequent plays it throws an error that the role already exists.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

azure_rm_roleassignment

ANSIBLE VERSION

Tested with Ansible 2.8.5 and 2.9.5 installed via Pip with the ansible[azure] packages

STEPS TO REPRODUCE
- name: Ensure SPN has 'network contributor' rights to Subnet
  azure_rm_roleassignment:
    scope: "{{ subnet_resource_id }}"
    assignee_object_id: "{{ spn_objectid }}"
    role_definition_id: "/subscriptions/{{ azure_subscription_id }}/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
    auth_source: cli
  environment:
    AZURE_CONFIG_DIR: "{{ azure_config_spn_role_assign }}"
  # Workaround for the bug
  failed_when: output_subnet_contributor.failed and 'The role assignment already exists' not in output_subnet_contributor.msg
  register: output_subnet_contributor
EXPECTED RESULTS

All plays run without error.

ACTUAL RESULTS

First play completes successfully, subsequent plays fail:

TASK [aks : Ensure SPN has 'network contributor' rights to Subnet] *****************************************************
fatal: [localhost]: FAILED! => {
    "changed": false
}

MSG:

Error creating role assignment: Azure Error: RoleAssignmentExists
Message: The role assignment already exists.
@Chaffelson
Copy link
Contributor

As a workaround for this, I have found that including a name allows it to be idempotently set, though you would have to manually clear the previous un-named registrations

@wrprice
Copy link
Author

wrprice commented Jun 8, 2020

@Chaffelson thanks for the potential workaround, but it's not working for me. If I set the name property to a string I compute that should be idempotent and yet unique, I get an error:

The role assignment ID 'ac5...fd7' is not valid. The role assignment ID must be a GUID.

My generated string is not a GUID. I suppose I could make it one, but it's not clear to me that I should do this. Can you post a working example of your workaround?

@Chaffelson
Copy link
Contributor

I construct the name string by combining the two parts of the role and assignee names, then push through to_uuid.
Remember to manually clean the assignments in the console before trying to apply this, as that appears to be predicated on the combination of role / scope / assignee ( though I haven't extensively tested the logic)

set_fact: unique_role_name: "{{ '-'.join([ _prefix, _suffix ]) | to_uuid }}"

Also, while you're using this sub component, you should know that state: absent will fail if the object does not exist, so you have to add something like the following:

- name: Refresh list of Role Assignments
  register: _fef0_az_rl_assgn_list
  azure_rm_roleassignment_info:
  scope: "{{ _fef0_az_rl_scp_subscr }}"

- name: Extract list of Azure Role Assignment Names
  set_fact:
  _fef0_az_rl_assgn_name_list: "{{ _fef0_az_rl_assgn_list.roleassignments | json_query('[*].name') }}"

- name: Process Azure Role Assignments
  when: ( _fef0_state == 'present' ) or (( _fef0_state == 'absent') and ( _fef0_rl_assgn_item.name in _fef0_az_rl_assgn_name_list ))
  block: `

@Fred-sun
Copy link
Collaborator

@wrprice Thank you for submitting this question. I checked this module. The previous design is not idempotent. I am discussing with the community maintainers whether we need to add this feature! Before determining the solution, you can follow the method suggested above, or delete and determine whether the segment exists before creating it to determine whether it needs to be created. Thank you!

@Fred-sun Fred-sun added the high_priority High priority label Aug 5, 2020
@RussTech
Copy link

I'm also running into this issue. Unfortunately, recreating all of our existing role assignments using the workaround posted above would not be feasible for us.

My less efficient workaround is to check for the assignment first with azure_rm_roleassignment_info. Then I've conditionalized azure_rm_roleassignment to run only if the assignment was not found.

@paultaiton
Copy link
Contributor

Is anyone actively working on this? I just submitted a PR for improving the roleassignment_info module, and the roleassignment module is next in my sights. I was planning on adding the ability to check for existing assignments matching the role, scope, and assignee, and if they match then consider it existing / no change, this will also make it idempotent if name is omitted and a random guid is created.

@Fred-sun
Copy link
Collaborator

Fred-sun commented Oct 15, 2020

@paultaiton We will review your PR submission as soon as possible. Thanks you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
high_priority High priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants