ansible-collections / amazon.aws

Ansible Collection for Amazon AWS
GNU General Public License v3.0
304 stars 332 forks source link

Tags not included when creating request causes IAM to reject call with IAM tag conditions enabled #1843

Closed TheToddLuci0 closed 9 months ago

TheToddLuci0 commented 10 months ago

Summary

When passed tags for a new resource, these are not passed with the CreateSecurityGroup API call. This causes a number of issues with tag based IAM policies.

This also introduces a potential race condition, where the resource exists in an untagged state, causing other tag based automation to trigger (for example, to remove the policy-violating resource) before the tags can be applied.

Issue Type

Bug Report

Component Name

ec2_security_group

Ansible Version

$ ansible --version
ansible [core 2.14.10]
  config file = /home/kali/git/controller/ansible.cfg
  configured module search path = ['/home/kali/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/kali/.local/pipx/venvs/ansible/lib/python3.11/site-packages/ansible
  ansible collection location = /home/kali/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/kali/.local/bin/ansible
  python version = 3.11.5 (main, Aug 29 2023, 15:31:31) [GCC 13.2.0] (/home/kali/.local/pipx/venvs/ansible/bin/python)
  jinja version = 3.1.2
  libyaml = True

Collection Versions

$ ansible-galaxy collection list
Collection                    Version
----------------------------- -------
amazon.aws                    6.3.0  
ansible.netcommon             5.1.2  
ansible.posix                 1.5.4  
ansible.utils                 2.10.3 
ansible.windows               1.14.0 
arista.eos                    6.0.1  
awx.awx                       22.6.0 
azure.azcollection            1.16.0 
check_point.mgmt              5.1.1  
chocolatey.chocolatey         1.5.1  
cisco.aci                     2.7.0  
cisco.asa                     4.0.1  
cisco.dnac                    6.7.3  
cisco.intersight              1.0.27 
cisco.ios                     4.6.1  
cisco.iosxr                   5.0.3  
cisco.ise                     2.5.14 
cisco.meraki                  2.15.3 
cisco.mso                     2.5.0  
cisco.nso                     1.0.3  
cisco.nxos                    4.4.0  
cisco.ucs                     1.10.0 
cloud.common                  2.1.4  
cloudscale_ch.cloud           2.3.1  
community.aws                 6.2.0  
community.azure               2.0.0  
community.ciscosmb            1.0.6  
community.crypto              2.15.0 
community.digitalocean        1.24.0 
community.dns                 2.6.0  
community.docker              3.4.8  
community.fortios             1.0.0  
community.general             7.3.0  
community.google              1.0.0  
community.grafana             1.5.4  
community.hashi_vault         5.0.0  
community.hrobot              1.8.1  
community.libvirt             1.2.0  
community.mongodb             1.6.1  
community.mysql               3.7.2  
community.network             5.0.0  
community.okd                 2.3.0  
community.postgresql          2.4.3  
community.proxysql            1.5.1  
community.rabbitmq            1.2.3  
community.routeros            2.9.0  
community.sap                 1.0.0  
community.sap_libs            1.4.1  
community.skydive             1.0.0  
community.sops                1.6.4  
community.vmware              3.9.0  
community.windows             1.13.0 
community.zabbix              2.1.0  
containers.podman             1.10.2 
cyberark.conjur               1.2.0  
cyberark.pas                  1.0.19 
dellemc.enterprise_sonic      2.2.0  
dellemc.openmanage            7.6.1  
dellemc.powerflex             1.7.0  
dellemc.unity                 1.7.1  
f5networks.f5_modules         1.25.1 
fortinet.fortimanager         2.2.1  
fortinet.fortios              2.3.1  
frr.frr                       2.0.2  
gluster.gluster               1.0.2  
google.cloud                  1.2.0  
grafana.grafana               2.1.5  
hetzner.hcloud                1.16.0 
hpe.nimble                    1.1.4  
ibm.qradar                    2.1.0  
ibm.spectrum_virtualize       1.12.0 
infinidat.infinibox           1.3.12 
infoblox.nios_modules         1.5.0  
inspur.ispim                  1.3.0  
inspur.sm                     2.3.0  
junipernetworks.junos         5.2.0  
kubernetes.core               2.4.0  
lowlydba.sqlserver            2.1.0  
microsoft.ad                  1.3.0  
netapp.aws                    21.7.0 
netapp.azure                  21.10.0
netapp.cloudmanager           21.22.0
netapp.elementsw              21.7.0 
netapp.ontap                  22.7.0 
netapp.storagegrid            21.11.1
netapp.um_info                21.8.0 
netapp_eseries.santricity     1.4.0  
netbox.netbox                 3.13.0 
ngine_io.cloudstack           2.3.0  
ngine_io.exoscale             1.0.0  
ngine_io.vultr                1.1.3  
openstack.cloud               2.1.0  
openvswitch.openvswitch       2.1.1  
ovirt.ovirt                   3.1.2  
purestorage.flasharray        1.20.0 
purestorage.flashblade        1.12.1 
purestorage.fusion            1.6.0  
sensu.sensu_go                1.14.0 
servicenow.servicenow         1.0.6  
splunk.es                     2.1.0  
t_systems_mms.icinga_director 1.33.1 
telekom_mms.icinga_director   1.34.1 
theforeman.foreman            3.12.0 
vmware.vmware_rest            2.3.1  
vultr.cloud                   1.8.0  
vyos.vyos                     4.1.0  
wti.remote                    1.0.5  

# /home/kali/.ansible/collections/ansible_collections
Collection             Version
---------------------- -------
awx.awx                23.2.0 
community.digitalocean 1.24.0 
community.docker       3.4.9  
flowerysong.hvault     0.2.0  

AWS SDK versions

$ pip show boto boto3 botocore
WARNING: Package(s) not found: boto
Name: boto3
Version: 1.28.59
Summary: The AWS SDK for Python
Home-page: https://github.com/boto/boto3
Author: Amazon Web Services
Author-email: 
License: Apache License 2.0
Location: /home/kali/.local/pipx/venvs/ansible/lib/python3.11/site-packages
Requires: botocore, jmespath, s3transfer
Required-by: 
---
Name: botocore
Version: 1.31.59
Summary: Low-level, data-driven core of boto 3.
Home-page: https://github.com/boto/botocore
Author: Amazon Web Services
Author-email: 
License: Apache License 2.0
Location: /home/kali/.local/pipx/venvs/ansible/lib/python3.11/site-packages
Requires: jmespath, python-dateutil, urllib3
Required-by: boto3, s3transfer

Configuration

$ ansible-config dump --only-changed
CACHE_PLUGIN(/home/kali/git/controller/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/kali/git/controller/ansible.cfg) = /tmp/facts_cache
CACHE_PLUGIN_TIMEOUT(/home/kali/git/controller/ansible.cfg) = 7200
CONFIG_FILE() = /home/kali/git/controller/ansible.cfg
DEFAULT_GATHERING(/home/kali/git/controller/ansible.cfg) = smart
DEFAULT_INTERNAL_POLL_INTERVAL(/home/kali/git/controller/ansible.cfg) = 0.001
HOST_KEY_CHECKING(/home/kali/git/controller/ansible.cfg) = False

OS / Environment

Linux kali 6.4.0-kali3-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.4.11-1kali1 (2023-08-21) x86_64 GNU/Linux

Steps to Reproduce

Playbook:

- name: Create an AWS Security Group (Allow-All)
  amazon.aws.ec2_security_group:
    name: "{{ codename }}-AllowAll"
    description: Allow all inbound/outbound traffic to/from {{ codename }} systems.
    region: "{{ region }}"
    vpc_id: "{{ vpc_id }}"
    rules:
      - proto: all
        cidr_ip: "0.0.0.0/0"
      - proto: all
        cidr_ipv6: ::/0
    rules_egress:
      - proto: all
        cidr_ip: "0.0.0.0/0"
      - proto: all
        cidr_ipv6: ::/0
    state: present
    tags:
      CODENAME: "{{ codename }}"
      CreatedBy: Controller

Relevant IAM policy snippet

        {
            "Sid": "AllowCreateSGInAttackVPC",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateSecurityGroup"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:XXXXXXXX:vpc/vpc-XXXXXXXXX",
                "arn:aws:ec2:*:XXXXXXXXXXXXX:security-group/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/CreatedBy": "Controller"
                }
            }
        },        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "ec2:CreateAction": [
                        "RunInstances",
                        "CreateSecurityGroup"
                    ]
                }
            }
        }

Expected Results

Security group should be created with valid tags

Actual Results

"msg": "Unable to add tags {'CreatedBy': 'Controller', 'CODENAME': 'test-with-new-keys'} to sg-XXXXXXX: An error occurred (UnauthorizedOperation) when calling the CreateTags operation: You are not authorized to perform this operation. User: arn:aws:iam::XXXXXXX:user/test-controller is not authorized to perform: ec2:CreateTags on resource: arn:aws:ec2:us-west-2:XXXXXXXX:security-group/sg-XXXXXXX because no identity-based policy allows the ec2:CreateTags action.

Code of Conduct

TheToddLuci0 commented 10 months ago

Via Ansible image image

VS with the CLI image

Note that the CLI does it in one API call, while Ansible uses two. In this case, the second fails since ec2:CreateTag is restricted to resource creation for this user.

tremble commented 10 months ago

Thanks for taking the time to open this issue.

This is actually a side effect of the fact that when the module was originally written the AWS EC2 APIs didn't support setting tags on creation, it had to be done as a separate API call. (Support for tagging during creation was only added to botocore in mid 2020, general tagging support for this module module was originally written in 2017).

The main change that needs to be made is setting the "ResourceTags" parameter as part of the create_security_group call. You can see an example of this type of change from ec2_vpc_nacl https://github.com/ansible-collections/community.aws/pull/1189/files would you be interested in creating a Pull Request to make this change? (I suspect most of the EC2 modules in this collection need the change too)