Skip to content

aws cloudformation_stack_set module not idempotent #103

Open
@naslanidis

Description

@naslanidis
SUMMARY

On running the cloudformation_stack_set module the first time it successfully creates the stackset and deploys the stack instances. On future runs of the play without nothing changed an additional update operation is run and changed is returned as true.

On each run it creates a new operation in the stackets console, again despite nothing being changed.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

cloudformation_stack_set AWS module

ANSIBLE VERSION
ansible 2.9.2
  config file = None
  configured module search path = ['/home/naslanidis/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/naslanidis/code/github/aws-organizations-poc/env/lib/python3.6/site-packages/ansible
  executable location = /home/naslanidis/code/github/aws-organizations-poc/env/bin/ansible
  python version = 3.6.9 (default, Apr 18 2020, 01:56:04) [GCC 8.4.0]
CONFIGURATION
$ ansible-config dump --only-changed
$ 
OS / ENVIRONMENT

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic

STEPS TO REPRODUCE
- name: Create test stackset
  cloudformation_stack_set:
    name: iam-core-stackset.yml
    description: Test stack in two accounts
    region: ap-southeast-2    
    state: present
    capabilities: CAPABILITY_NAMED_IAM
    template: "{{role_path}}/templates/iam-core-stackset.yml"
    accounts: [12345679878]
    regions:
    - ap-southeast-2
EXPECTED RESULTS

On first run it works fine:

TASK [baseline-stacksets : Create test core stackset] *****************************************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP ************************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

On second run without change it chould be changed=0 and nothing changes.

ACTUAL RESULTS

On the 2nd (and any future) run of the play:

TASK [baseline-stacksets : Create test core stackset] *****************************************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP ************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Each time I run the module a new stackset operation is created. This should not happen when nothing has changed in the task.

It's possible this was a design choice but essentially there's no comparison being done to compare the existing stack facts against the arguments in the ansible task. In the below, if there's no existing_stack_set, one is created. Else, the update_stack_set function is called. I feel there should be some comparison being done between the stack_params dict and the existing_stack_set dict to determine if an update is required.

    if state == 'present':
        if not existing_stack_set:
            # on create this parameter has a different name, and cannot be referenced later in the job log
            stack_params['ClientRequestToken'] = 'Ansible-StackSet-Create-{0}'.format(operation_uuid)
            changed = True
            create_stack_set(module, stack_params, cfn)
        else:
            stack_params['OperationId'] = 'Ansible-StackSet-Update-{0}'.format(operation_uuid)
            operation_ids.append(stack_params['OperationId'])
            if module.params.get('regions'):
                stack_params['OperationPreferences'] = get_operation_preferences(module)
            changed |= update_stack_set(module, stack_params, cfn)

additional operations for each run

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions