diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:18:37 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-05 16:18:37 +0000 |
commit | 5d7eda1e172f8e396536a8fbd6f85b4b991290e8 (patch) | |
tree | b18be36b43a1abdab0d40ecc8e4c8de2dbcd65c0 /ansible_collections/amazon/aws/tests | |
parent | Adding debian version 9.5.1+dfsg-1. (diff) | |
download | ansible-5d7eda1e172f8e396536a8fbd6f85b4b991290e8.tar.xz ansible-5d7eda1e172f8e396536a8fbd6f85b4b991290e8.zip |
Merging upstream version 10.0.0+dfsg.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/amazon/aws/tests')
61 files changed, 2135 insertions, 300 deletions
diff --git a/ansible_collections/amazon/aws/tests/integration/targets/aws_region_info/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/aws_region_info/tasks/main.yml index d83b14440..0b07bec77 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/aws_region_info/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/aws_region_info/tasks/main.yml @@ -7,7 +7,7 @@ region: "{{ aws_region }}" block: - name: List available Regions - community.aws.aws_region_info: + amazon.aws.aws_region_info: register: regions - name: check task return attributes vars: @@ -22,7 +22,7 @@ - '"region_name" in first_region' - name: List available Regions - check_mode - community.aws.aws_region_info: + amazon.aws.aws_region_info: register: check_regions - name: check task return attributes - check_mode vars: @@ -37,7 +37,7 @@ - '"region_name" in first_region' - name: Filter available Regions using - ("region-name") - community.aws.aws_region_info: + amazon.aws.aws_region_info: filters: region-name: us-west-1 register: us_west_1 @@ -58,7 +58,7 @@ - first_region.region_name == 'us-west-1' - name: Filter available Regions using _ ("region_name") - community.aws.aws_region_info: + amazon.aws.aws_region_info: filters: region_name: us-west-2 register: us_west_2 @@ -79,7 +79,7 @@ - first_region.region_name == 'us-west-2' - name: Filter available Regions using _ and - to check precedence - community.aws.aws_region_info: + amazon.aws.aws_region_info: filters: region-name: eu-west-1 region_name: eu-central-1 diff --git a/ansible_collections/amazon/aws/tests/integration/targets/backup_selection/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/backup_selection/tasks/main.yml index 7cf27ce8c..11d550d48 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/backup_selection/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/backup_selection/tasks/main.yml @@ -12,7 +12,7 @@ # ============================================================ - name: Create an IAM Role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ backup_iam_role_name }}" assume_role_policy_document: '{{ lookup("file", "backup-policy.json") }}' create_instance_profile: false @@ -745,7 +745,7 @@ ignore_errors: true - name: Delete IAM role created during this test - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ backup_iam_role_name }}" state: absent ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/cloudtrail/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/cloudtrail/tasks/main.yml index 3d4f60144..6f9e8fe48 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/cloudtrail/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/cloudtrail/tasks/main.yml @@ -141,7 +141,7 @@ register: kms_key2 - name: Create CloudWatch IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: present name: "{{ cloudwatch_role }}" assume_role_policy_document: "{{ lookup('template', 'cloudwatch-assume-policy.j2') }}" @@ -167,7 +167,7 @@ policy_json: "{{ lookup('template', 'cloudwatch-policy.j2') | to_json }}" - name: Create CloudWatch IAM Role with no kms permissions - community.aws.iam_role: + amazon.aws.iam_role: state: present name: "{{ cloudwatch_no_kms_role }}" assume_role_policy_document: "{{ lookup('template', 'cloudtrail-no-kms-assume-policy.j2') }}" @@ -551,7 +551,7 @@ state: present name: "{{ cloudtrail_name }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" register: output check_mode: true - ansible.builtin.assert: @@ -563,28 +563,28 @@ state: present name: "{{ cloudtrail_name }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" register: output - ansible.builtin.assert: that: - output is changed - output.trail.name == cloudtrail_name - output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn - - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: Set CloudWatch Log Group (no change) amazon.aws.cloudtrail: state: present name: "{{ cloudtrail_name }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" register: output - ansible.builtin.assert: that: - output is not changed - output.trail.name == cloudtrail_name - output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn - - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: No-op update to trail amazon.aws.cloudtrail: @@ -596,7 +596,7 @@ - output is not changed - output.trail.name == cloudtrail_name - output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn - - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: Get the trail info with CloudWatch Log Group amazon.aws.cloudtrail_info: @@ -608,49 +608,49 @@ ansible.builtin.assert: that: - info.trail_list[0].cloud_watch_logs_log_group_arn == output_cloudwatch_log_group.arn - - info.trail_list[0].cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - info.trail_list[0].cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: Update CloudWatch Log Group (CHECK MODE) amazon.aws.cloudtrail: state: present name: "{{ cloudtrail_name }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group2.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" register: output check_mode: true - ansible.builtin.assert: that: - output is changed - output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn - - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: Update CloudWatch Log Group amazon.aws.cloudtrail: state: present name: "{{ cloudtrail_name }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group2.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" register: output - ansible.builtin.assert: that: - output is changed - output.trail.name == cloudtrail_name - output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn - - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: Update CloudWatch Log Group (no change) amazon.aws.cloudtrail: state: present name: "{{ cloudtrail_name }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group2.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" register: output - ansible.builtin.assert: that: - output is not changed - output.trail.name == cloudtrail_name - output.trail.cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn - - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - output.trail.cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn - name: Get the trail info with CloudWatch Log Group after update amazon.aws.cloudtrail_info: @@ -662,7 +662,7 @@ ansible.builtin.assert: that: - info.trail_list[0].cloud_watch_logs_log_group_arn == output_cloudwatch_log_group2.arn - - info.trail_list[0].cloud_watch_logs_role_arn == output_cloudwatch_role.arn + - info.trail_list[0].cloud_watch_logs_role_arn == output_cloudwatch_role.iam_role.arn #- name: 'Remove CloudWatch Log Group (CHECK MODE)' # amazon.aws.cloudtrail: @@ -1332,7 +1332,7 @@ # Assume role to a role with Denied access to KMS - amazon.aws.sts_assume_role: - role_arn: "{{ output_cloudwatch_no_kms_role.arn }}" + role_arn: "{{ output_cloudwatch_no_kms_role.iam_role.arn }}" role_session_name: cloudtrailNoKms region: "{{ aws_region }}" register: noKms_assumed_role @@ -1438,7 +1438,7 @@ s3_key_prefix: "{{ cloudtrail_prefix }}" sns_topic_name: "{{ sns_topic }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" is_multi_region_trail: true include_global_events: true enable_log_file_validation: true @@ -1468,7 +1468,7 @@ s3_key_prefix: "{{ cloudtrail_prefix }}" sns_topic_name: "{{ sns_topic }}" cloudwatch_logs_log_group_arn: "{{ output_cloudwatch_log_group.arn }}" - cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.arn }}" + cloudwatch_logs_role_arn: "{{ output_cloudwatch_role.iam_role.arn }}" is_multi_region_trail: true include_global_events: true enable_log_file_validation: true @@ -1572,7 +1572,7 @@ policy_name: CloudWatch ignore_errors: true - name: Delete CloudWatch IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ cloudwatch_role }}" ignore_errors: true @@ -1584,7 +1584,7 @@ policy_name: CloudWatchNokms ignore_errors: true - name: Delete CloudWatch No KMS IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ cloudwatch_no_kms_role }}" ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/ec2_instance_iam_instance_role/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/ec2_instance_iam_instance_role/tasks/main.yml index 14f44c2eb..336ebdb08 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/ec2_instance_iam_instance_role/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/ec2_instance_iam_instance_role/tasks/main.yml @@ -7,7 +7,7 @@ region: "{{ aws_region }}" block: - name: Create IAM role for test - community.aws.iam_role: + amazon.aws.iam_role: state: present name: "{{ first_iam_role }}" assume_role_policy_document: "{{ lookup('file','assume-role-policy.json') }}" @@ -17,7 +17,7 @@ register: iam_role - name: Create second IAM role for test - community.aws.iam_role: + amazon.aws.iam_role: state: present name: "{{ second_iam_role }}" assume_role_policy_document: "{{ lookup('file','assume-role-policy.json') }}" @@ -46,7 +46,7 @@ - ansible.builtin.assert: that: - - instance_with_role.instances[0].iam_instance_profile.arn == iam_role.arn.replace(":role/", ":instance-profile/") + - instance_with_role.instances[0].iam_instance_profile.arn == iam_role.iam_role.arn.replace(":role/", ":instance-profile/") - name: Make instance with an instance_role(check mode) amazon.aws.ec2_instance: @@ -55,7 +55,7 @@ image_id: "{{ ec2_ami_id }}" security_groups: "{{ sg.group_id }}" instance_type: "{{ ec2_instance_type }}" - instance_role: "{{ iam_role.arn.replace(':role/', ':instance-profile/') }}" + instance_role: "{{ iam_role.iam_role.arn.replace(':role/', ':instance-profile/') }}" vpc_subnet_id: "{{ testing_subnet_a.subnet.id }}" tags: TestId: "{{ ec2_instance_tag_TestId }}" @@ -86,7 +86,7 @@ image_id: "{{ ec2_ami_id }}" security_groups: "{{ sg.group_id }}" instance_type: "{{ ec2_instance_type }}" - instance_role: "{{ iam_role_2.arn.replace(':role/', ':instance-profile/') }}" + instance_role: "{{ iam_role_2.iam_role.arn.replace(':role/', ':instance-profile/') }}" vpc_subnet_id: "{{ testing_subnet_a.subnet.id }}" tags: TestId: "{{ ec2_instance_tag_TestId }}" @@ -105,7 +105,7 @@ - ansible.builtin.assert: that: - - updates_instance_info.instances[0].iam_instance_profile.arn == iam_role_2.arn.replace(":role/", ":instance-profile/") + - updates_instance_info.instances[0].iam_instance_profile.arn == iam_role_2.iam_role.arn.replace(":role/", ":instance-profile/") - updates_instance_info.instances[0].instance_id == instance_with_role.instances[0].instance_id always: @@ -119,7 +119,7 @@ ignore_errors: true - name: Delete IAM role for test - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ item }}" delete_instance_profile: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/ec2_vol/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/ec2_vol/tasks/main.yml index edeccb4ea..3867885a7 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/ec2_vol/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/ec2_vol/tasks/main.yml @@ -685,7 +685,6 @@ ansible.builtin.assert: that: - not delete_volume_result_idem.changed - - '"Volume "+ volume2.volume_id +" does not exist" in delete_volume_result_idem.msg' # Originally from ec2_vol_info diff --git a/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/defaults/main.yml index b591e4ae6..399f98acf 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/defaults/main.yml @@ -4,6 +4,7 @@ resource_short: "{{ '%0.8x' % ((16**8) | random(seed=resource_prefix)) }}" alb_name: alb-test-{{ resource_short }} alb_2_name: alb-test-2-{{ resource_short }} +alb_name_multiple_listener_test: alb-test-{{ resource_short }}-lt tg_name: alb-test-{{ resource_short }} tg_2_name: alb-test-2-{{ resource_short }} vpc_cidr: 10.{{ 256 | random(seed=resource_prefix) }}.0.0/16 @@ -26,3 +27,15 @@ elb_access_log_account_id_map: us-gov-west-1: "048591011584" elb_account_id: "{{ elb_access_log_account_id_map[aws_region] }}" + +local_certs: + - priv_key: "{{ remote_tmp_dir }}/private-1.pem" + cert: "{{ remote_tmp_dir }}/public-1.pem" + csr: "{{ remote_tmp_dir }}/csr-1.csr" + domain: elb-classic.{{ tiny_prefix }}.ansible.test + name: "{{ resource_prefix }}_{{ resource_prefix }}_1" + - priv_key: "{{ remote_tmp_dir }}/private-2.pem" + cert: "{{ remote_tmp_dir }}/public-2.pem" + csr: "{{ remote_tmp_dir }}/csr-2.csr" + domain: elb-classic.{{ tiny_prefix }}.ansible.test + name: "{{ resource_prefix }}_{{ resource_prefix }}_2" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/meta/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/meta/main.yml new file mode 100644 index 000000000..bef04ab7f --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/meta/main.yml @@ -0,0 +1,4 @@ +--- +dependencies: + - setup_ec2_facts + - setup_remote_tmp_dir diff --git a/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/alb_with_multiple_listener_certs.yml b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/alb_with_multiple_listener_certs.yml new file mode 100644 index 000000000..af55c29bf --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/alb_with_multiple_listener_certs.yml @@ -0,0 +1,127 @@ +- name: Run tests + block: + - name: Generate private key for local certs + community.crypto.openssl_privatekey: + path: "{{ item.priv_key }}" + type: RSA + size: 2048 + with_items: "{{ local_certs }}" + + - name: Generate an OpenSSL Certificate Signing Request for own certs + community.crypto.openssl_csr: + path: "{{ item.csr }}" + privatekey_path: "{{ item.priv_key }}" + common_name: "{{ item.domain }}" + with_items: "{{ local_certs }}" + + - name: Generate a Self Signed OpenSSL certificate for own certs + community.crypto.x509_certificate: + provider: selfsigned + path: "{{ item.cert }}" + csr_path: "{{ item.csr }}" + privatekey_path: "{{ item.priv_key }}" + selfsigned_digest: sha256 + register: cert_create_result + with_items: "{{ local_certs }}" + + - name: upload certificates + community.aws.acm_certificate: + name_tag: "{{ item.name }}" + certificate: "{{ lookup('file', item.cert ) }}" + private_key: "{{ lookup('file', item.priv_key ) }}" + state: present + tags: + Application: search + Environment: development + purge_tags: false + register: upload + with_items: "{{ local_certs }}" + until: upload is succeeded + retries: 5 + delay: 10 + + - ansible.builtin.set_fact: + cert_1_arn: "{{ upload.results[0].certificate.arn }}" + cert_2_arn: "{{ upload.results[1].certificate.arn }}" + + - name: Create a target group for testing + community.aws.elb_target_group: + name: "{{ tg_name }}" + protocol: http + port: 80 + vpc_id: "{{ vpc_id }}" + state: present + + - name: Create an ALB with listener having multiple certificates + amazon.aws.elb_application_lb: + name: "{{ alb_name_multiple_listener_test }}" + subnets: "{{ public_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: present + purge_listeners: False + listeners: + - Protocol: HTTPS + Port: 446 + SslPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06 + Certificates: # The ARN of the certificate + - CertificateArn: "{{ cert_1_arn }}" + - CertificateArn: "{{ cert_2_arn }}" + DefaultActions: + - Type: forward + TargetGroupName: "{{ tg_name }}" + register: alb + + - name: Gather information about a particular ALB given its ARN #returns only default cert + amazon.aws.elb_application_lb_info: + load_balancer_arns: + - "{{ alb.load_balancer_arn }}" + register: alb_info + + - name: obtain information about a certificate 1 + community.aws.acm_certificate_info: + certificate_arn: "{{ cert_1_arn }}" + register: cert_1_info + + - name: obtain information about a certificate 2 + community.aws.acm_certificate_info: + certificate_arn: "{{ cert_2_arn }}" + register: cert_2_info + + - name: Assert that both certificiates are in use by test load balancer + ansible.builtin.assert: + that: + - cert_1_info.certificates[0].in_use_by[0] == alb_info.load_balancers[0].load_balancer_arn + - cert_2_info.certificates[0].in_use_by[0] == alb_info.load_balancers[0].load_balancer_arn + + always: + - name: Delete test ALB + amazon.aws.elb_application_lb: + name: "{{ alb_name_multiple_listener_test }}" + subnets: "{{ public_subnets }}" + security_groups: "{{ sec_group.group_id }}" + state: absent + purge_listeners: False + listeners: + - Protocol: HTTPS + Port: 446 + SslPolicy: ELBSecurityPolicy-TLS13-1-2-2021-06 + Certificates: # The ARN of the certificate + - CertificateArn: "{{ cert_1_arn }}" + - CertificateArn: "{{ cert_2_arn }}" + DefaultActions: + - Type: forward + TargetGroupName: "{{ tg_name }}" + ignore_errors: true + + - name: delete a certificate with a particular ARN + community.aws.acm_certificate: + certificate_arn: "{{ item }}" + state: absent + register: delete_acm + with_items: + - "{{ cert_1_arn }}" + - "{{ cert_2_arn }}" + retries: 5 + delay: 5 + until: delete_acm is not failed + ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/main.yml index 6edc6416d..28d4bdbdd 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/elb_application_lb/tasks/main.yml @@ -133,6 +133,10 @@ encryption: aws:kms policy: "{{ lookup('template', 'policy.json') }}" + + - name: Run tests for creating ALB with listener having multiple certificates + ansible.builtin.import_tasks: alb_with_multiple_listener_certs.yml + - name: Create an ALB (invalid - SslPolicy is required when Protocol == HTTPS) amazon.aws.elb_application_lb: name: "{{ alb_name }}" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_group/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_group/tasks/main.yml index 54015a446..269cd51ec 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_group/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_group/tasks/main.yml @@ -15,7 +15,7 @@ state: present - name: Create Safe IAM Managed Policy - community.aws.iam_managed_policy: + amazon.aws.iam_managed_policy: state: present policy_name: "{{ custom_policy_name }}" policy_description: A safe (deny-all) managed policy @@ -54,7 +54,7 @@ state: absent - name: Remove Safe IAM Managed Policy - community.aws.iam_managed_policy: + amazon.aws.iam_managed_policy: state: absent policy_name: "{{ custom_policy_name }}" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_instance_profile/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_instance_profile/tasks/main.yml index 794b7a4ae..cbebc966a 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_instance_profile/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_instance_profile/tasks/main.yml @@ -17,7 +17,7 @@ # Prepare - name: Prepare IAM Roles - community.aws.iam_role: + amazon.aws.iam_role: state: present name: "{{ item }}" path: "{{ test_path }}" @@ -504,7 +504,7 @@ - "{{ test_role }}-2" - name: Remove IAM Roles - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ item }}" path: "{{ test_path }}" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/defaults/main.yml index 51ece2c3a..4257634b7 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/defaults/main.yml @@ -2,3 +2,6 @@ policy_name: "{{ resource_prefix }}-policy" policy_path: "/ansible-test-{{ tiny_prefix }}/" policy_description: "An example Managed Policy description" +test_role: "{{ resource_prefix }}-mp-role" +test_user: "{{ resource_prefix }}-mp-user" +test_group: "{{ resource_prefix }}-mp-group" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/files/deny-assume.json b/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/files/deny-assume.json new file mode 100644 index 000000000..73e877158 --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/files/deny-assume.json @@ -0,0 +1,10 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Principal": { "Service": "ec2.amazonaws.com" }, + "Effect": "Deny" + } + ] +} diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/tasks/main.yml index c6ab19a74..ec4238b85 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_managed_policy/tasks/main.yml @@ -9,6 +9,21 @@ collections: - amazon.aws block: + - name: Create IAM group + amazon.aws.iam_group: + name: "{{ test_group }}" + state: present + - name: Create IAM user + amazon.aws.iam_user: + name: "{{ test_user }}" + state: present + - name: Create IAM role + amazon.aws.iam_role: + name: "{{ test_role }}" + assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}' + create_instance_profile: false + state: present + ## Test policy creation - name: Create IAM managed policy - check mode amazon.aws.iam_managed_policy: @@ -448,14 +463,60 @@ - result.policy.tags["Tag C"] == "Value C" - result.policy.tags["tag d"] == "value d" + - name: Attach managed policy to group + amazon.aws.iam_group: + name: "{{ test_group }}" + state: present + managed_policies: + - "{{ policy_name }}" + - name: Attach managed policy to user + amazon.aws.iam_user: + name: "{{ test_user }}" + state: present + managed_policies: + - "{{ policy_name }}" + - name: Attach managed policy to role + amazon.aws.iam_role: + name: "{{ test_role }}" + state: present + assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}' + managed_policies: + - "{{ policy_name }}" + - name: Delete IAM managed policy amazon.aws.iam_managed_policy: policy_name: "{{ policy_name }}" state: absent + - name: Delete IAM group + amazon.aws.iam_group: + name: "{{ test_group }}" + state: absent + - name: Delete IAM user + amazon.aws.iam_user: + name: "{{ test_user }}" + state: absent + - name: Delete IAM role + amazon.aws.iam_role: + name: "{{ test_role }}" + state: absent + always: - name: Delete IAM managed policy amazon.aws.iam_managed_policy: policy_name: "{{ policy_name }}" state: absent ignore_errors: true # noqa: ignore-errors + + - name: Delete IAM group + amazon.aws.iam_group: + name: "{{ test_group }}" + state: absent + - name: Delete IAM user + amazon.aws.iam_user: + name: "{{ test_user }}" + state: absent + - name: Delete IAM role + amazon.aws.iam_role: + name: "{{ test_role }}" + state: absent diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_password_policy/tasks/main.yaml b/ansible_collections/amazon/aws/tests/integration/targets/iam_password_policy/tasks/main.yaml index 9b4fa7167..8d497813a 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_password_policy/tasks/main.yaml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_password_policy/tasks/main.yaml @@ -9,7 +9,7 @@ - amazon.aws block: - name: set iam password policy - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: present min_pw_length: 8 require_symbols: false @@ -28,7 +28,7 @@ - result.changed - name: verify iam password policy has been created - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: present min_pw_length: 8 require_symbols: false @@ -47,7 +47,7 @@ - not result.changed - name: update iam password policy with different settings - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: present min_pw_length: 15 require_symbols: true @@ -67,7 +67,7 @@ # Test for regression of #59102 - name: update iam password policy without expiry - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: present min_pw_length: 15 require_symbols: true @@ -83,7 +83,7 @@ - result.changed - name: remove iam password policy - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: absent register: result @@ -93,7 +93,7 @@ - result.changed - name: verify password policy has been removed - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: absent register: result @@ -103,6 +103,6 @@ - not result.changed always: - name: remove iam password policy - community.aws.iam_password_policy: + amazon.aws.iam_password_policy: state: absent register: result diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_policy/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_policy/tasks/main.yml index 9ed065036..afae59a0e 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_policy/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_policy/tasks/main.yml @@ -19,7 +19,7 @@ - result is changed - name: Create role for tests - community.aws.iam_role: + amazon.aws.iam_role: state: present name: "{{ iam_name }}" assume_role_policy_document: "{{ lookup('file','no_trust.json') }}" @@ -30,7 +30,7 @@ - result is changed - name: Create group for tests - community.aws.iam_group: + amazon.aws.iam_group: state: present name: "{{ iam_name }}" register: result @@ -60,12 +60,12 @@ name: "{{ iam_name }}" ignore_errors: true - name: Remove role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ iam_name }}" ignore_errors: true - name: Remove group - community.aws.iam_group: + amazon.aws.iam_group: state: absent name: "{{ iam_name }}" ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/defaults/main.yml index 8d7bdfb1d..57a4b9e2b 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/defaults/main.yml @@ -1,6 +1,7 @@ --- test_role: "{{ resource_prefix }}-role" -test_path: /{{ resource_prefix }}/ +test_path: "/{{ resource_prefix }}/" +bad_test_path: "{{ resource_prefix }}" safe_managed_policy: AWSDenyAll custom_policy_name: "{{ resource_prefix }}-denyall" -boundary_policy: arn:aws:iam::aws:policy/AWSDenyAll +boundary_policy: "arn:aws:iam::aws:policy/AWSDenyAll" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/boundary_policy.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/boundary_policy.yml index 706853c67..f24731f08 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/boundary_policy.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/boundary_policy.yml @@ -1,6 +1,6 @@ --- - name: Create minimal role with no boundary policy - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role @@ -10,7 +10,7 @@ - iam_role.iam_role.role_name == test_role - name: Configure Boundary Policy (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false boundary: "{{ boundary_policy }}" @@ -21,7 +21,7 @@ - iam_role is changed - name: Configure Boundary Policy - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false boundary: "{{ boundary_policy }}" @@ -32,7 +32,7 @@ - iam_role.iam_role.role_name == test_role - name: Configure Boundary Policy (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false boundary: "{{ boundary_policy }}" @@ -43,7 +43,7 @@ - iam_role is not changed - name: Configure Boundary Policy (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false boundary: "{{ boundary_policy }}" @@ -54,7 +54,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after adding boundary policy - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -77,7 +77,7 @@ - role_info.iam_roles[0].role_name == test_role - name: Remove IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/complex_role_creation.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/complex_role_creation.yml index 7195c5887..e0a33d7ca 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/complex_role_creation.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/complex_role_creation.yml @@ -1,6 +1,6 @@ --- - name: Complex IAM Role (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}' boundary: "{{ boundary_policy }}" @@ -20,7 +20,7 @@ - iam_role is changed - name: iam_role_info after Complex Role creation in check_mode - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -29,7 +29,7 @@ - role_info.iam_roles | length == 0 - name: Complex IAM Role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}' boundary: "{{ boundary_policy }}" @@ -59,7 +59,7 @@ - '"role_id" in iam_role.iam_role' - name: Complex IAM role (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}' boundary: "{{ boundary_policy }}" @@ -79,7 +79,7 @@ - iam_role is not changed - name: Complex IAM role (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" assume_role_policy_document: '{{ lookup("file", "deny-assume.json") }}' boundary: "{{ boundary_policy }}" @@ -99,7 +99,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after Role creation - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/creation_deletion.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/creation_deletion.yml index 9c81019c8..694c4d16b 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/creation_deletion.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/creation_deletion.yml @@ -2,12 +2,12 @@ - name: Try running some rapid fire create/delete tests block: - name: Minimal IAM Role without instance profile (rapid) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role - name: Minimal IAM Role without instance profile (rapid) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role_again @@ -17,12 +17,12 @@ - iam_role_again is not changed - name: Remove IAM Role (rapid) - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" register: iam_role - name: Remove IAM Role (rapid) - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" register: iam_role_again @@ -32,12 +32,12 @@ - iam_role_again is not changed - name: Minimal IAM Role without instance profile (rapid) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role - name: Remove IAM Role (rapid) - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" register: iam_role_again @@ -50,14 +50,14 @@ # Role Creation # (without Instance profile) - name: iam_role_info before Role creation (no args) - community.aws.iam_role_info: + amazon.aws.iam_role_info: register: role_info - ansible.builtin.assert: that: - role_info is succeeded - name: iam_role_info before Role creation (search for test role) - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -66,7 +66,7 @@ - role_info.iam_roles | length == 0 - name: Minimal IAM Role (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role @@ -76,7 +76,7 @@ - iam_role is changed - name: iam_role_info after Role creation in check_mode - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -85,7 +85,7 @@ - role_info.iam_roles | length == 0 - name: Minimal IAM Role without instance profile - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role @@ -106,7 +106,7 @@ - '"role_id" in iam_role.iam_role' - name: Minimal IAM Role without instance profile (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role @@ -116,7 +116,7 @@ - iam_role is not changed - name: Minimal IAM Role without instance profile (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: false register: iam_role @@ -126,7 +126,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after Role creation - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -151,7 +151,7 @@ - role_info.iam_roles[0].tags | length == 0 - name: Remove IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true @@ -161,7 +161,7 @@ - iam_role is changed - name: iam_role_info after Role deletion - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -173,7 +173,7 @@ # (with path) - name: Minimal IAM Role with path (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: "{{ test_path }}" register: iam_role @@ -183,7 +183,7 @@ - iam_role is changed - name: Minimal IAM Role with path - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: "{{ test_path }}" register: iam_role @@ -203,7 +203,7 @@ - '"role_id" in iam_role.iam_role' - name: Minimal IAM Role with path (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: "{{ test_path }}" register: iam_role @@ -213,7 +213,7 @@ - iam_role is not changed - name: Minimal IAM Role with path (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: "{{ test_path }}" register: iam_role @@ -223,7 +223,7 @@ - iam_role.iam_role.role_name == test_role - name: Minimal IAM Role with updated path (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: "{{ test_path }}subpath/" register: iam_role @@ -234,7 +234,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after Role creation - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -260,7 +260,7 @@ - role_info.iam_roles[0].tags | length == 0 - name: iam_role_info after Role creation (searching a path) - community.aws.iam_role_info: + amazon.aws.iam_role_info: path_prefix: "{{ test_path }}" register: role_info - ansible.builtin.assert: @@ -285,8 +285,34 @@ - role_info.iam_roles[0].role_name == test_role - role_info.iam_roles[0].tags | length == 0 +- name: iam_role_info after Role creation (searching a path without / prefix and suffix) + amazon.aws.iam_role_info: + path_prefix: "{{ bad_test_path }}" + register: role_info +- ansible.builtin.assert: + that: + - role_info is succeeded + - role_info.iam_roles | length == 1 + - role_info.iam_roles[0].arn.startswith("arn") + - role_info.iam_roles[0].arn.endswith("role" + test_path + test_role ) + - '"assume_role_policy_document" in role_info.iam_roles[0]' + - '"create_date" in role_info.iam_roles[0]' + - '"description" not in role_info.iam_roles[0]' + - role_info.iam_roles[0].inline_policies | length == 0 + - role_info.iam_roles[0].instance_profiles | length == 1 + - role_info.iam_roles[0].instance_profiles[0].instance_profile_name == test_role + - role_info.iam_roles[0].instance_profiles[0].arn.startswith("arn") + - role_info.iam_roles[0].instance_profiles[0].arn.endswith("instance-profile" + test_path + test_role) + - role_info.iam_roles[0].managed_policies | length == 0 + - role_info.iam_roles[0].max_session_duration == 3600 + - '"permissions_boundary" not in role_info.iam_roles[0]' + - role_info.iam_roles[0].path == test_path + - role_info.iam_roles[0].role_id == iam_role.iam_role.role_id + - role_info.iam_roles[0].role_name == test_role + - role_info.iam_roles[0].tags | length == 0 + - name: Remove IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" path: "{{ test_path }}" @@ -297,7 +323,7 @@ - iam_role is changed - name: iam_role_info after Role deletion - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -309,7 +335,7 @@ # (with Instance profile) - name: Minimal IAM Role with instance profile - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: true register: iam_role @@ -319,7 +345,7 @@ - iam_role is changed - name: Minimal IAM Role with instance profile - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: true register: iam_role @@ -339,7 +365,7 @@ - '"role_id" in iam_role.iam_role' - name: Minimal IAM Role wth instance profile (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: true register: iam_role @@ -349,7 +375,7 @@ - iam_role is not changed - name: Minimal IAM Role wth instance profile (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" create_instance_profile: true register: iam_role @@ -359,7 +385,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after Role creation - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/description_update.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/description_update.yml index 0cb9a46af..edb88f7dd 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/description_update.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/description_update.yml @@ -1,6 +1,6 @@ --- - name: Add Description (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role {{ resource_prefix }} check_mode: true @@ -10,7 +10,7 @@ - iam_role is changed - name: Add Description - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role {{ resource_prefix }} register: iam_role @@ -21,7 +21,7 @@ - iam_role.iam_role.description == "Ansible Test Role "+resource_prefix - name: Add Description (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role {{ resource_prefix }} register: iam_role @@ -31,7 +31,7 @@ - iam_role is not changed - name: Add Description (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role {{ resource_prefix }} register: iam_role @@ -42,7 +42,7 @@ - iam_role.iam_role.description == "Ansible Test Role "+resource_prefix - name: iam_role_info after adding Description - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -70,7 +70,7 @@ # ------------------------------------------------------------------------------------------ - name: Update Description (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role (updated) {{ resource_prefix }} check_mode: true @@ -80,7 +80,7 @@ - iam_role is changed - name: Update Description - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role (updated) {{ resource_prefix }} register: iam_role @@ -91,7 +91,7 @@ - iam_role.iam_role.description == 'Ansible Test Role (updated) '+resource_prefix - name: Update Description (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role (updated) {{ resource_prefix }} register: iam_role @@ -101,7 +101,7 @@ - iam_role is not changed - name: Update Description (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" description: Ansible Test Role (updated) {{ resource_prefix }} register: iam_role @@ -112,7 +112,7 @@ - iam_role.iam_role.description == 'Ansible Test Role (updated) '+resource_prefix - name: iam_role_info after updating Description - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/inline_policy_update.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/inline_policy_update.yml index 0091045e8..5b3e42458 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/inline_policy_update.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/inline_policy_update.yml @@ -14,7 +14,7 @@ policy_name: inline-policy-b policy_json: '{{ lookup("file", "deny-all-b.json") }}' - name: iam_role_info after attaching inline policies (using iam_policy) - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/main.yml index b7a62db9f..21e25d9e3 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/main.yml @@ -34,7 +34,7 @@ assume_deny_policy: '{{ lookup("file", "deny-assume.json") | from_json }}' - ansible.builtin.include_tasks: parameter_checks.yml - name: Create Safe IAM Managed Policy - community.aws.iam_managed_policy: + amazon.aws.iam_managed_policy: state: present policy_name: "{{ custom_policy_name }}" policy_description: A safe (deny-all) managed policy @@ -60,23 +60,23 @@ # Cleanup - name: Remove IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true ignore_errors: true - name: Remove IAM Role (with path) - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" path: "{{ test_path }}" delete_instance_profile: true ignore_errors: true - name: iam_role_info after Role deletion - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" ignore_errors: true - name: Remove test managed policy - community.aws.iam_managed_policy: + amazon.aws.iam_managed_policy: state: absent policy_name: "{{ custom_policy_name }}" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/max_session_update.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/max_session_update.yml index fe43bcfc8..576e6b24c 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/max_session_update.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/max_session_update.yml @@ -1,6 +1,6 @@ --- - name: Update Max Session Duration (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" max_session_duration: 43200 check_mode: true @@ -10,7 +10,7 @@ - iam_role is changed - name: Update Max Session Duration - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" max_session_duration: 43200 register: iam_role @@ -21,7 +21,7 @@ - iam_role.iam_role.max_session_duration == 43200 - name: Update Max Session Duration (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" max_session_duration: 43200 register: iam_role @@ -30,7 +30,7 @@ - iam_role is not changed - name: Update Max Session Duration (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" max_session_duration: 43200 register: iam_role @@ -40,7 +40,7 @@ - iam_role is not changed - name: iam_role_info after updating Max Session Duration - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/parameter_checks.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/parameter_checks.yml index 2cf46eebf..545072674 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/parameter_checks.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/parameter_checks.yml @@ -1,7 +1,7 @@ --- # Parameter Checks - name: Friendly message when creating an instance profile and adding a boundary profile - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" boundary: "{{ boundary_policy }}" register: iam_role @@ -14,7 +14,7 @@ - '"false" in iam_role.msg' - name: Friendly message when boundary profile is not an ARN - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" boundary: AWSDenyAll create_instance_profile: false @@ -28,7 +28,7 @@ - name: Friendly message when "present" without assume_role_policy_document module_defaults: { amazon.aws.iam_role: {}} - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" register: iam_role ignore_errors: true @@ -39,7 +39,7 @@ - '"assume_role_policy_document" in iam_role.msg' - name: Maximum Session Duration needs to be between 1 and 12 hours - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" max_session_duration: 3599 register: iam_role @@ -50,7 +50,7 @@ - '"max_session_duration must be between" in iam_role.msg' - name: Maximum Session Duration needs to be between 1 and 12 hours - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" max_session_duration: 43201 register: iam_role @@ -61,7 +61,7 @@ - '"max_session_duration must be between" in iam_role.msg' - name: Role Paths must start with / - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: test/ register: iam_role @@ -72,7 +72,7 @@ - '"path must begin and end with /" in iam_role.msg' - name: Role Paths must end with / - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" path: /test register: iam_role diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/policy_update.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/policy_update.yml index 4fa5cd6d2..27b911ae7 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/policy_update.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/policy_update.yml @@ -1,6 +1,6 @@ --- - name: Add Managed Policy (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -12,7 +12,7 @@ - iam_role is changed - name: Add Managed Policy - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -24,7 +24,7 @@ - iam_role.iam_role.role_name == test_role - name: Add Managed Policy (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -36,7 +36,7 @@ - iam_role is not changed - name: Add Managed Policy (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -48,7 +48,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after adding Managed Policy - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -80,7 +80,7 @@ # ------------------------------------------------------------------------------------------ - name: Update Managed Policy without purge (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -92,7 +92,7 @@ - iam_role is changed - name: Update Managed Policy without purge - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -104,7 +104,7 @@ - iam_role.iam_role.role_name == test_role - name: Update Managed Policy without purge (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -116,7 +116,7 @@ - iam_role is not changed - name: Update Managed Policy without purge (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_policies: false managed_policy: @@ -128,7 +128,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after updating Managed Policy without purge - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -161,7 +161,7 @@ # Managed Policies are purged by default - name: Update Managed Policy with purge (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" managed_policy: - "{{ custom_policy_name }}" @@ -172,7 +172,7 @@ - iam_role is changed - name: Update Managed Policy with purge - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" managed_policy: - "{{ custom_policy_name }}" @@ -183,7 +183,7 @@ - iam_role.iam_role.role_name == test_role - name: Update Managed Policy with purge (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" managed_policy: - "{{ custom_policy_name }}" @@ -194,7 +194,7 @@ - iam_role is not changed - name: Update Managed Policy with purge (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" managed_policy: - "{{ custom_policy_name }}" @@ -205,7 +205,7 @@ - iam_role.iam_role.role_name == test_role - name: iam_role_info after updating Managed Policy with purge - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/role_removal.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/role_removal.yml index 8761bda73..f4e79252a 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/role_removal.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/role_removal.yml @@ -1,6 +1,6 @@ --- - name: Remove IAM Role (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true @@ -11,7 +11,7 @@ - iam_role is changed - name: iam_role_info after deleting role in check mode - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -20,7 +20,7 @@ - role_info.iam_roles | length == 1 - name: Remove IAM Role - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true @@ -30,7 +30,7 @@ - iam_role is changed - name: iam_role_info after deleting role - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -39,7 +39,7 @@ - role_info.iam_roles | length == 0 - name: Remove IAM Role (should be gone already) - check mode - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true @@ -50,7 +50,7 @@ - iam_role is not changed - name: Remove IAM Role (should be gone already) - community.aws.iam_role: + amazon.aws.iam_role: state: absent name: "{{ test_role }}" delete_instance_profile: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/tags_update.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/tags_update.yml index e74820d77..45d703cc1 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/tags_update.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_role/tasks/tags_update.yml @@ -1,6 +1,6 @@ --- - name: Add Tag (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: ValueA @@ -11,7 +11,7 @@ - iam_role is changed - name: Add Tag - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: ValueA @@ -25,7 +25,7 @@ - iam_role.iam_role.tags.TagA == "ValueA" - name: Add Tag (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: ValueA @@ -36,7 +36,7 @@ - iam_role is not changed - name: Add Tag (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: ValueA @@ -49,7 +49,7 @@ - iam_role.iam_role.tags.TagA == "ValueA" - name: iam_role_info after adding Tags - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -79,7 +79,7 @@ # ------------------------------------------------------------------------------------------ - name: Update Tag (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: AValue @@ -90,7 +90,7 @@ - iam_role is changed - name: Update Tag - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: AValue @@ -103,7 +103,7 @@ - iam_role.iam_role.tags.TagA == "AValue" - name: Update Tag (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: AValue @@ -114,7 +114,7 @@ - iam_role is not changed - name: Update Tag (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" tags: TagA: AValue @@ -127,7 +127,7 @@ - iam_role.iam_role.tags.TagA == "AValue" - name: iam_role_info after updating Tag - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -157,7 +157,7 @@ # ------------------------------------------------------------------------------------------ - name: Add second Tag without purge (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: false tags: @@ -169,7 +169,7 @@ - iam_role is changed - name: Add second Tag without purge - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: false tags: @@ -183,7 +183,7 @@ - iam_role.iam_role.tags.TagB == "ValueB" - name: Add second Tag without purge (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: false tags: @@ -195,7 +195,7 @@ - iam_role is not changed - name: Add second Tag without purge (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: false tags: @@ -209,7 +209,7 @@ - iam_role.iam_role.tags.TagB == "ValueB" - name: iam_role_info after adding second Tag without purge - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: @@ -241,7 +241,7 @@ # ------------------------------------------------------------------------------------------ - name: Purge first tag (CHECK MODE) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: true tags: @@ -253,7 +253,7 @@ - iam_role is changed - name: Purge first tag - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: true tags: @@ -267,7 +267,7 @@ - iam_role.iam_role.tags.TagB == "ValueB" - name: Purge first tag (no change) - check mode - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: true tags: @@ -278,7 +278,7 @@ - iam_role is not changed - name: Purge first tag (no change) - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ test_role }}" purge_tags: true tags: @@ -292,7 +292,7 @@ - iam_role.iam_role.tags.TagB == "ValueB" - name: iam_role_info after purging first Tag - community.aws.iam_role_info: + amazon.aws.iam_role_info: name: "{{ test_role }}" register: role_info - ansible.builtin.assert: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/iam_user/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/iam_user/tasks/main.yml index 675b9a5b1..870dd4931 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/iam_user/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/iam_user/tasks/main.yml @@ -160,7 +160,7 @@ ansible.builtin.include_tasks: deletion.yml always: - name: Remove group - community.aws.iam_group: + amazon.aws.iam_group: name: "{{ test_group }}" state: absent ignore_errors: true # noqa: ignore-errors diff --git a/ansible_collections/amazon/aws/tests/integration/targets/inventory_aws_ec2/playbooks/test_inventory_ssm.yml b/ansible_collections/amazon/aws/tests/integration/targets/inventory_aws_ec2/playbooks/test_inventory_ssm.yml index c8e820aad..161fdc6e6 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/inventory_aws_ec2/playbooks/test_inventory_ssm.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/inventory_aws_ec2/playbooks/test_inventory_ssm.yml @@ -31,7 +31,7 @@ # Create VPC, subnet, security group, and find image_id to create instance - ansible.builtin.include_tasks: tasks/setup.yml - name: Ensure IAM instance role exists - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ iam_role_name }}" assume_role_policy_document: "{{ lookup('file', 'files/ec2-trust-policy.json') }}" state: present @@ -117,7 +117,7 @@ always: - name: Delete IAM role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ iam_role_name }}" state: absent wait: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_grants.yml b/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_grants.yml index ff97a1a09..d9ad140e9 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_grants.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_grants.yml @@ -10,7 +10,7 @@ amazon.aws.aws_caller_info: register: aws_caller_info - name: Create an IAM role that can do nothing - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ kms_key_alias }}" state: present assume_role_policy_document: @@ -353,7 +353,7 @@ pending_window: 7 ignore_errors: true # noqa: ignore-errors - name: Remove the IAM role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ kms_key_alias }}" state: absent ignore_errors: true # noqa: ignore-errors diff --git a/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_modify.yml b/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_modify.yml index 1adb65094..8a0390615 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_modify.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/kms_key/roles/kms_key/tasks/test_modify.yml @@ -10,7 +10,7 @@ amazon.aws.aws_caller_info: register: aws_caller_info - name: Create an IAM role that can do nothing - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ kms_key_alias }}" state: present assume_role_policy_document: @@ -286,7 +286,7 @@ pending_window: 7 ignore_errors: true # noqa: ignore-errors - name: Remove the IAM role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ kms_key_alias }}" state: absent ignore_errors: true # noqa: ignore-errors diff --git a/ansible_collections/amazon/aws/tests/integration/targets/lambda/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/lambda/tasks/main.yml index dd8392d20..3720b4d79 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/lambda/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/lambda/tasks/main.yml @@ -16,7 +16,7 @@ when: (lookup('env', 'HOME')) # Preparation - name: create minimal lambda role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" assume_role_policy_document: '{{ lookup("file", "minimal_trust_policy.json") }}' create_instance_profile: false @@ -807,7 +807,7 @@ - "{{ lambda_function_name }}_4" - name: ensure role has been removed at end of test - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" state: absent ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/lambda_alias/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/lambda_alias/tasks/main.yml index d6b8e0d6e..e96aa8269 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/lambda_alias/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/lambda_alias/tasks/main.yml @@ -12,7 +12,7 @@ # ============================================================== # Preparation - name: create minimal lambda role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" assume_role_policy_document: '{{ lookup("file", "minimal_trust_policy.json") }}' create_instance_profile: false @@ -616,7 +616,7 @@ state: absent ignore_errors: true - name: ensure role has been removed at end of test - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" state: absent delete_instance_profile: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/main.yml index f06482a62..1e49d1373 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/main.yml @@ -6,11 +6,10 @@ secret_key: "{{ aws_secret_key }}" session_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" - collections: - - community.general block: - name: Create test resources setup ansible.builtin.import_tasks: setup.yml + - name: Create DynamoDB stream event mapping (trigger) - check_mode amazon.aws.lambda_event: state: present diff --git a/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/setup.yml b/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/setup.yml index fa2668fd5..1f77a5e40 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/setup.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/setup.yml @@ -33,7 +33,7 @@ when: (lookup('env', 'HOME')) - name: create minimal lambda role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" assume_role_policy_document: '{{ lookup("file", "minimal_trust_policy.json")}}' create_instance_profile: false diff --git a/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/teardown.yml b/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/teardown.yml index 476465a6e..2f13e1de4 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/teardown.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/lambda_event/tasks/teardown.yml @@ -26,7 +26,7 @@ state: absent - name: Delete the role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" assume_role_policy_document: '{{ lookup("file", "minimal_trust_policy.json")}}' state: absent diff --git a/ansible_collections/amazon/aws/tests/integration/targets/lambda_policy/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/lambda_policy/tasks/main.yml index c3c73aaf2..e222f9fa6 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/lambda_policy/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/lambda_policy/tasks/main.yml @@ -12,7 +12,7 @@ - community.aws block: - name: create minimal lambda role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" assume_role_policy_document: '{{ lookup("file", "minimal_trust_policy.json") }}' create_instance_profile: false @@ -50,7 +50,7 @@ path: "{{ output_dir }}/mini_http_lambda.py" dest: "{{ output_dir }}/mini_http_lambda.zip" - name: create minimal lambda role - community.aws.iam_role: + amazon.aws.iam_role: name: ansible_lambda_role assume_role_policy_document: "{{ lookup('file', 'minimal_trust_policy.json', convert_data=False) }}" create_instance_profile: false @@ -143,7 +143,7 @@ register: destroy_result ignore_errors: true - name: Clean up test role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ lambda_role_name }}" state: absent ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/aliases b/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/aliases new file mode 100644 index 000000000..e26025382 --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/aliases @@ -0,0 +1,3 @@ +cloud/aws +rds_cluster_param_group_info +rds_engine_versions_info diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/defaults/main.yaml b/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/defaults/main.yaml new file mode 100644 index 000000000..8758e70cf --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/defaults/main.yaml @@ -0,0 +1,7 @@ +--- +rds_cluster_param_group_name: "{{ resource_prefix }}-cluster-param-group" +rds_engine: postgres +resource_tags: + resource_prefix: "{{ resource_prefix }}" + some: tag + another: tag diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/tasks/main.yaml b/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/tasks/main.yaml new file mode 100644 index 000000000..3eb85f617 --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_cluster_param_group/tasks/main.yaml @@ -0,0 +1,328 @@ +--- +- module_defaults: + group/aws: + region: "{{ aws_region }}" + access_key: "{{ aws_access_key }}" + secret_key: "{{ aws_secret_key }}" + session_token: "{{ security_token | default(omit) }}" + + block: + - name: Gather information about RDS engine version + amazon.aws.rds_engine_versions_info: + engine: "{{ rds_engine }}" + default_only: true + register: engine_versions + + - name: Set variable for RDS param group family + ansible.builtin.set_fact: + dbparam_group_family: "{{ engine_versions.db_engine_versions.0.db_parameter_group_family }}" + + # Test create using check_mode=true + - name: Create RDS cluster parameter group (check_mode=true) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + check_mode: true + register: create_checkmode + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Assert that the RDS cluster parameter was not created (using check_mode=true) + ansible.builtin.assert: + that: + - create_checkmode is changed + - cluster_params.db_cluster_parameter_groups | length == 0 + + # Test create RDS cluster parameter group + - name: Create RDS cluster parameter group + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + register: create_group + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Assert that the RDS cluster parameter was created + ansible.builtin.assert: + that: + - create_group is changed + - create_group.db_cluster_parameter_group.db_cluster_parameter_group_arn + - create_group.db_cluster_parameter_group.db_cluster_parameter_group_name == rds_cluster_param_group_name + - create_group.db_cluster_parameter_group.db_parameter_group_family == dbparam_group_family + - cluster_params.db_cluster_parameter_groups | length == 1 + + # Test create RDS cluster parameter group (idempotency) + - name: Create RDS cluster parameter group (idempotency) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + register: create_idempotency + + - name: Validate that module did not report change + ansible.builtin.assert: + that: + - create_idempotency is not changed + + # Test adding tag to existing RDS cluster parameter group (check_mode=true) + - name: Update existing RDS cluster parameter group with tags (check_mode=true) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + tags: "{{ resource_tags }}" + register: create_tag + check_mode: true + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Validate that the resource has not been updated with tags (check_mode) + ansible.builtin.assert: + that: + - create_tag is changed + - cluster_params.db_cluster_parameter_groups.0.tags == {} + + # Test adding tag to existing RDS cluster parameter group + - name: Update existing RDS cluster parameter group with tags + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + tags: "{{ resource_tags }}" + register: create_tag + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Validate that the resource has been updated with tags + ansible.builtin.assert: + that: + - create_tag is changed + - cluster_params.db_cluster_parameter_groups.0.tags == resource_tags + + # Test adding tag to existing RDS cluster parameter group (idempotency) + - name: Update existing RDS cluster parameter group with tags (idempotency) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + tags: "{{ resource_tags }}" + register: create_tag_idempotency + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Validate that the module did not report change and the resource tag remain unchanged + ansible.builtin.assert: + that: + - create_tag_idempotency is not changed + - cluster_params.db_cluster_parameter_groups.0.tags == resource_tags + + # Test adding not modifiable parameter + - name: Update RDS cluster param group with not modifiable parameter + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + parameters: + - parameter_name: archive_library + parameter_value: test + apply_method: immediate + register: not_modifiable + ignore_errors: true + + - name: Ensure module failed to update not modifiable parameter + ansible.builtin.assert: + that: + - not_modifiable is failed + - '"The parameter archive_library cannot be modified" in not_modifiable.msg' + + # Test adding invalid parameter + - name: Update RDS cluster param group with invalid parameter + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + parameters: + - parameter_name: invalid_fake + parameter_value: test + apply_method: immediate + register: invalid_param + ignore_errors: true + + - name: Ensure module failed to update invalid parameter + ansible.builtin.assert: + that: + - invalid_param is failed + - '"Could not find parameter with name: invalid_fake" in invalid_param.msg' + + # Test Modify parameters + - name: Modify RDS cluster parameter group with new parameters (check_mode) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + parameters: + - parameter_name: array_nulls + parameter_value: "0" + apply_method: immediate + - parameter_name: authentication_timeout + parameter_value: "50" + apply_method: immediate + register: update_param_check_mode + check_mode: true + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + include_parameters: all + register: initial_params + no_log: true # very spammy + + - name: Assert that the task executed in check_mode reported change, while the parameters remain unchanged + ansible.builtin.assert: + that: + - update_param_check_mode is changed + - "'parameter_value' not in array_nulls_param" + - "'parameter_value' not in auth_timeout_param" + vars: + array_nulls_param: "{{ initial_params.db_cluster_parameter_groups.0.db_parameters | selectattr('parameter_name', 'equalto', 'array_nulls') | first }}" + auth_timeout_param: "{{ initial_params.db_cluster_parameter_groups.0.db_parameters | selectattr('parameter_name', 'equalto', 'authentication_timeout') | first }}" + + - name: Modify RDS cluster parameter group with new parameters + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + parameters: + - parameter_name: array_nulls + parameter_value: "0" + apply_method: immediate + - parameter_name: authentication_timeout + parameter_value: "50" + apply_method: immediate + register: update_parameters + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + include_parameters: user + register: cluster_params + + - name: Assert that the parameters are updated correctly + ansible.builtin.assert: + that: + - update_parameters is changed + - cluster_params.db_cluster_parameter_groups.0.db_parameters | selectattr('parameter_name', 'equalto', 'array_nulls') | first | community.general.json_query('parameter_value') == "0" + - cluster_params.db_cluster_parameter_groups.0.db_parameters | selectattr('parameter_name', 'equalto', 'authentication_timeout') | first | community.general.json_query('parameter_value') == "50" + + # Test Modify parameters (idempotency) + - name: Modify RDS cluster parameter group with new parameters (idempotency with check_mode) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + parameters: + - parameter_name: array_nulls + parameter_value: "0" + apply_method: immediate + - parameter_name: authentication_timeout + parameter_value: "50" + apply_method: immediate + register: update_idempotency_check_mode + + - name: Ensure task executed using check_mode did not reported change + ansible.builtin.assert: + that: + - update_idempotency_check_mode is not changed + + - name: Modify RDS cluster parameter group with new parameters (idempotency) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + db_parameter_group_family: "{{ dbparam_group_family }}" + description: "RDS cluster param group for Engine {{ engine_versions.db_engine_versions.0.engine_version }}" + parameters: + - parameter_name: array_nulls + parameter_value: "0" + apply_method: immediate + - parameter_name: authentication_timeout + parameter_value: "50" + apply_method: immediate + register: update_idempotency + + - name: Ensure module did not report change + ansible.builtin.assert: + that: + - update_idempotency is not changed + + # Test delete RDS cluster parameter group (check_mode=true) + - name: Delete existing RDS cluster parameter group (check_mode=true) + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + state: absent + register: delete_cluster_param_checkmode + check_mode: true + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Validate that module execution reported change but the RDS cluster param group was not deleted + assert: + that: + - delete_cluster_param_checkmode is changed + - cluster_params.db_cluster_parameter_groups | length == 1 + + # Test delete RDS cluster parameter group + - name: Delete existing RDS cluster parameter group + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + state: absent + register: delete_cluster_param + + - name: Describe RDS parameter group + amazon.aws.rds_cluster_param_group_info: + name: "{{ rds_cluster_param_group_name }}" + register: cluster_params + + - name: Validate that module execution reported change and the RDS cluster param group is deleted + ansible.builtin.assert: + that: + - delete_cluster_param is changed + - cluster_params.db_cluster_parameter_groups | length == 0 + + # Test delete RDS cluster parameter group (idempotency) + - name: Delete existing RDS cluster parameter group + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + state: absent + register: delete_cluster_param + + - name: Ensure module did not report change + ansible.builtin.assert: + that: + - delete_cluster_param is not changed + + always: + - name: Delete existing RDS cluster parameter group + amazon.aws.rds_cluster_param_group: + name: "{{ rds_cluster_param_group_name }}" + state: absent + register: delete_cluster_param + ignore_errors: true diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/defaults/main.yml index f2b794609..c7b6d0de9 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/defaults/main.yml @@ -14,4 +14,4 @@ storage_type: io1 iops: 1000 # For mariadb tests -mariadb_engine_version: 10.6.10 +mariadb_engine_version: 10.11.7 diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/tasks/main.yml index e4d9daa60..51ff777ea 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_complex/tasks/main.yml @@ -23,7 +23,7 @@ ignore_errors: true - name: Create an enhanced monitoring role - community.aws.iam_role: + amazon.aws.iam_role: assume_role_policy_document: "{{ lookup('file','files/enhanced_monitoring_assume_policy.json') }}" name: "{{ instance_id }}-role" state: present @@ -91,7 +91,7 @@ preferred_maintenance_window: "{{ preferred_maintenance_window }}" auto_minor_version_upgrade: false monitoring_interval: "{{ monitoring_interval }}" - monitoring_role_arn: "{{ enhanced_monitoring_role.arn }}" + monitoring_role_arn: "{{ enhanced_monitoring_role.iam_role.arn }}" iops: "{{ iops }}" port: 1150 max_allocated_storage: 150 @@ -115,7 +115,7 @@ preferred_maintenance_window: "{{ preferred_maintenance_window }}" auto_minor_version_upgrade: false monitoring_interval: "{{ monitoring_interval }}" - monitoring_role_arn: "{{ enhanced_monitoring_role.arn }}" + monitoring_role_arn: "{{ enhanced_monitoring_role.iam_role.arn }}" iops: "{{ iops }}" port: 1150 max_allocated_storage: 150 @@ -143,7 +143,7 @@ preferred_maintenance_window: "{{ preferred_maintenance_window }}" auto_minor_version_upgrade: false monitoring_interval: "{{ monitoring_interval }}" - monitoring_role_arn: "{{ enhanced_monitoring_role.arn }}" + monitoring_role_arn: "{{ enhanced_monitoring_role.iam_role.arn }}" iops: "{{ iops }}" port: 1150 max_allocated_storage: 150 @@ -166,7 +166,7 @@ preferred_maintenance_window: "{{ preferred_maintenance_window }}" auto_minor_version_upgrade: false monitoring_interval: "{{ monitoring_interval }}" - monitoring_role_arn: "{{ enhanced_monitoring_role.arn }}" + monitoring_role_arn: "{{ enhanced_monitoring_role.iam_role.arn }}" iops: "{{ iops }}" port: 1150 max_allocated_storage: 150 @@ -190,7 +190,7 @@ ignore_errors: true - name: Remove enhanced monitoring role - community.aws.iam_role: + amazon.aws.iam_role: assume_role_policy_document: "{{ lookup('file','files/enhanced_monitoring_assume_policy.json') }}" name: "{{ instance_id }}-role" state: absent diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/defaults/main.yml index 0384232d5..0e09b9c4c 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/defaults/main.yml @@ -7,4 +7,4 @@ db_instance_class: db.t3.micro allocated_storage: 20 # For mariadb tests -mariadb_engine_version: 10.6.10 +mariadb_engine_version: 10.11.7 diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/tasks/main.yml index 4e33789f3..e440bbc42 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_modify/tasks/main.yml @@ -82,7 +82,7 @@ - '"is not valid for adding IAM roles" in result.msg' # TODO: test modifying db_subnet_group_name, db_security_groups, db_parameter_group_name, option_group_name, - # monitoring_role_arn, monitoring_interval, domain, domain_iam_role_name, cloudwatch_logs_export_configuration + # monitoring_role_arn, monitoring_interval, domain, domain_iam_role_name # ------------------------------------------------------------------------------------------ - name: Modify the storage type without immediate application - check_mode @@ -306,6 +306,193 @@ - db_info.instances[0].ca_certificate_identifier == "rds-ca-ecc384-g1" # Test modifying CA certificate identifier Complete------------------------------------------- + # Test modifying cloudwatch log exports ------------------------------------------- + - name: Enable all cloudwatch log exports - check_mode + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: ["audit", "error", "general", "slowquery"] + register: result + check_mode: true + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + - name: Assert that cloudwatch log exports has been modified - check_mode + ansible.builtin.assert: + that: + - result is changed + - result is not failed + - db_info.instances[0].enabled_cloudwatch_logs_exports is not defined + + - name: Enable all cloudwatch log exports + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: ["audit", "error", "general", "slowquery"] + register: result + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + # It applies immediately but takes a couple seconds + until: + - db_info.instances[0].db_instance_status == 'available' + - not db_info.instances[0].pending_modified_values + retries: 10 + delay: 20 + + - name: Assert that cloudwatch log exports has been modified + ansible.builtin.assert: + that: + - result is changed + - result is not failed + - db_info.instances[0].enabled_cloudwatch_logs_exports | length == 4 + + - name: Enable all cloudwatch log exports - idempotent + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: ["audit", "error", "general", "slowquery"] + register: result + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + - name: Assert that cloudwatch log exports has not been modified + ansible.builtin.assert: + that: + - result is not changed + - result is not failed + - not result.pending_modified_values + - db_info.instances[0].enabled_cloudwatch_logs_exports | length == 4 + + - name: Disable some cloudwatch log exports - check_mode + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: ["audit", "error"] + register: result + check_mode: true + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + - name: Assert that cloudwatch log exports has been modified - check_mode + ansible.builtin.assert: + that: + - result is changed + - result is not failed + - db_info.instances[0].enabled_cloudwatch_logs_exports | length == 4 + + - name: Disable some cloudwatch log exports + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: ["audit", "error"] + register: result + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + until: + - db_info.instances[0].db_instance_status == 'available' + - not db_info.instances[0].pending_modified_values + retries: 10 + delay: 20 + + - name: Assert that cloudwatch log exports has been modified + ansible.builtin.assert: + that: + - result is changed + - result is not failed + - db_info.instances[0].enabled_cloudwatch_logs_exports | length == 2 + + - name: Disable all cloudwatch log exports - no purge + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: [] + purge_cloudwatch_logs_exports: false + register: result + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + - name: Assert that cloudwatch log exports has not been modified + ansible.builtin.assert: + that: + - result is not changed + - result is not failed + - not result.pending_modified_values + - db_info.instances[0].enabled_cloudwatch_logs_exports | length == 2 + + - name: Disable all cloudwatch log exports - check_mode + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: [] + register: result + check_mode: true + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + - name: Assert that cloudwatch log exports has been modified - check_mode + ansible.builtin.assert: + that: + - result is changed + - result is not failed + - db_info.instances[0].enabled_cloudwatch_logs_exports | length == 2 + + - name: Disable all cloudwatch log exports + amazon.aws.rds_instance: + state: present + db_instance_identifier: "{{ modified_instance_id }}" + enable_cloudwatch_logs_exports: [] + register: result + vars: + ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}" + + - name: Get current cloudwatch log exports + amazon.aws.rds_instance_info: + db_instance_identifier: "{{ modified_instance_id }}" + register: db_info + until: + - db_info.instances[0].db_instance_status == 'available' + - not db_info.instances[0].pending_modified_values + retries: 10 + delay: 20 + + - name: Assert that cloudwatch log exports has been modified + ansible.builtin.assert: + that: + - result is changed + - result is not failed + - db_info.instances[0].enabled_cloudwatch_logs_exports is not defined + # Test modifying cloudwatch log exports Complete------------------------------------------- + always: - name: Delete the instance amazon.aws.rds_instance: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_snapshot/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_snapshot/defaults/main.yml index d193876e7..e82f395a8 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_snapshot/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_instance_snapshot/defaults/main.yml @@ -8,7 +8,7 @@ password: "{{ lookup('password', '/dev/null') }}" db_instance_class: db.t3.micro allocated_storage: 10 engine: mariadb -mariadb_engine_version: 10.6.10 +mariadb_engine_version: 10.11.7 # Create snapshot snapshot_id: "{{ instance_id }}-snapshot" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_option_group/defaults/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_option_group/defaults/main.yml index e0f04005f..70a5946bf 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_option_group/defaults/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_option_group/defaults/main.yml @@ -1,7 +1,7 @@ --- option_group_name: "{{ resource_prefix }}rds-option-group" engine_name: mysql -major_engine_version: 5.6 +major_engine_version: 8.0 option_group_description: "{{ resource_prefix }}rds-option-group test" instance_id: "{{ resource_prefix }}" username: test diff --git a/ansible_collections/amazon/aws/tests/integration/targets/rds_param_group/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/rds_param_group/tasks/main.yml index 663ee68df..4751e56e8 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/rds_param_group/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/rds_param_group/tasks/main.yml @@ -22,7 +22,7 @@ block: # ============================================================ - name: test empty parameter group - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -36,7 +36,7 @@ - result.changed - name: test empty parameter group - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -54,7 +54,7 @@ # ============================================================ - name: test empty parameter group with no arguments changes nothing - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -68,7 +68,7 @@ - not result.changed - name: test empty parameter group with no arguments changes nothing - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -82,7 +82,7 @@ # ============================================================ - name: test adding numeric tag - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -98,7 +98,7 @@ that: - result.changed - name: test adding numeric tag - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -123,7 +123,7 @@ # ============================================================ - name: test modifying rds parameter group engine/family (warning displayed) - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine_to_modify_to }}" description: "{{ rds_param_group.description }}" @@ -143,7 +143,7 @@ # ============================================================ - name: test tagging existing group - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -160,7 +160,7 @@ that: - result.changed - name: test tagging existing group - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -186,7 +186,7 @@ # ============================================================ - name: test repeating tagging existing group - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -212,7 +212,7 @@ - result.tags["NewTag"] == 'hello' - name: test repeating tagging existing group - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -238,7 +238,7 @@ # ============================================================ - name: test deleting tags from existing group - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -254,7 +254,7 @@ that: - result.changed - name: test deleting tags from existing group - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -277,7 +277,7 @@ # ============================================================ - name: test state=absent with engine defined (expect changed=true) - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" state: absent @@ -290,7 +290,7 @@ - result.changed - name: test state=absent with engine defined (expect changed=true) - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" state: absent @@ -303,7 +303,7 @@ # ============================================================ - name: test creating group with parameters - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -325,7 +325,7 @@ - result.changed - name: test creating group with parameters - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -355,7 +355,7 @@ # ============================================================ - name: test repeating group with parameters - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -377,7 +377,7 @@ - not result.changed - name: test repeating group with parameters - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -407,7 +407,7 @@ # ============================================================ - name: test state=absent with engine defined (expect changed=true) - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" state: absent @@ -419,7 +419,7 @@ that: - result.changed - name: test state=absent with engine defined (expect changed=true) - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" state: absent @@ -432,7 +432,7 @@ # ============================================================ - name: test repeating state=absent (expect changed=false) - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" state: absent @@ -445,7 +445,7 @@ that: - not result.changed - name: test repeating state=absent (expect changed=false) - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" state: absent @@ -459,7 +459,7 @@ # ============================================================ - name: test creating group with more than 20 parameters - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -473,7 +473,7 @@ that: - result.changed - name: test creating group with more than 20 parameters - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -488,7 +488,7 @@ # ============================================================ - name: test creating group with more than 20 parameters - CHECK_MODE - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -502,7 +502,7 @@ that: - not result.changed - name: test creating group with more than 20 parameters - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" engine: "{{ rds_param_group.engine }}" description: "{{ rds_param_group.description }}" @@ -518,7 +518,7 @@ always: # ============================================================ - name: test state=absent (expect changed=false) - amazon.aws.rds_param_group: + amazon.aws.rds_instance_param_group: name: "{{ rds_param_group.name }}" state: absent register: result diff --git a/ansible_collections/amazon/aws/tests/integration/targets/s3_bucket_info/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/s3_bucket_info/tasks/main.yml index f532c13a1..1b5c3172e 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/s3_bucket_info/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/s3_bucket_info/tasks/main.yml @@ -1,5 +1,5 @@ --- -- name: Test community.aws.aws_s3_bucket_info +- name: Test s3_bucket_info module_defaults: group/aws: access_key: "{{ aws_access_key }}" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/s3_object/library/test_s3_upload_multipart.py b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/library/test_s3_upload_multipart.py new file mode 100644 index 000000000..a95275865 --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/library/test_s3_upload_multipart.py @@ -0,0 +1,137 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +DOCUMENTATION = r""" +--- +module: test_s3_upload_multipart +short_description: Create object using multipart upload +description: + - This module is used to create object into S3 bucket using multipart upload. + - Multipart upload allows to upload a single object as a set of parts. + - This module is exclusively used to test collection `amazon.aws`. +options: + bucket: + description: + - Bucket name. + required: true + type: str + object: + description: + - Key name of the object. + type: str + required: true + part_size: + description: + - Part size in MB. + type: int + default: 10 + parts: + description: + - Number of parts. + type: int + default: 6 +author: + - "Aubin Bikouo (@abikouo)" +extends_documentation_fragment: + - amazon.aws.common.modules + - amazon.aws.region.modules + - amazon.aws.tags + - amazon.aws.boto3 +""" + + +try: + import boto3 + import botocore +except ImportError: + pass # Handled by AnsibleAWSModule + +import random +import string + +from ansible.module_utils.common.dict_transformations import snake_dict_to_camel_dict + +from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.s3 import s3_extra_params + + +def generate_content(length): + return "".join([random.choice(string.ascii_letters + string.digits) for i in range(length)]) + + +def updload_parts(s3, parts, part_size, **kwargs): + multiparts = [] + for part_id in range(1, parts + 1): + response = s3.upload_part( + Body=str.encode(generate_content(part_size * 1024 * 1024)), PartNumber=part_id, **kwargs + ) + + multiparts.append( + { + "PartNumber": part_id, + "ETag": response.get("ETag"), + } + ) + return multiparts + + +def main(): + argument_spec = dict( + bucket=dict(required=True), + object=dict(required=True), + parts=dict(type="int", default=6), + part_size=dict(type="int", default=10), + ) + + module = AnsibleAWSModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) + + bucket = module.params.get("bucket") + object = module.params.get("object") + part_size = module.params.get("part_size") + parts = module.params.get("parts") + + extra_params = s3_extra_params(module.params) + retry_decorator = AWSRetry.jittered_backoff() + try: + s3 = module.client("s3", retry_decorator=retry_decorator, **extra_params) + except ( + botocore.exceptions.ClientError, + botocore.exceptions.BotoCoreError, + boto3.exceptions.Boto3Error, + ) as e: + module.fail_json_aws(e, msg="Failed to connect to AWS") + + # create multipart upload + response = s3.create_multipart_upload(Bucket=bucket, Key=object) + upload_id = response.get("UploadId") + + # upload parts + upload_params = { + "Bucket": bucket, + "Key": object, + "UploadId": upload_id, + } + + multiparts = updload_parts(s3, parts, part_size, **upload_params) + + # complete the upload + response = s3.complete_multipart_upload( + Bucket=bucket, + Key=object, + MultipartUpload={"Parts": multiparts}, + UploadId=upload_id, + ) + + response.pop("ResponseMetadata", None) + module.exit_json(changed=True, s3_object=snake_dict_to_camel_dict(response)) + + +if __name__ == "__main__": + main() diff --git a/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_multipart_upload.yml b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_multipart_upload.yml new file mode 100644 index 000000000..edab77b6e --- /dev/null +++ b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_multipart_upload.yml @@ -0,0 +1,185 @@ +- name: Test copying object create using multipart upload + vars: + test_bucket: "{{ resource_prefix }}-multipart" + test_versioned_bucket: "{{ resource_prefix }}-multipart-versioned" + obj_metadata: + some: meta_info + test: ci + block: + # Create Sample bucket + - name: Create bucket with name '{{ test_bucket }}' + amazon.aws.s3_bucket: + name: "{{ test_bucket }}" + state: present + + - name: Create object into bucket using multipart upload + test_s3_upload_multipart: + access_key: "{{ aws_access_key }}" + secret_key: "{{ aws_secret_key }}" + session_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + bucket: "{{ test_bucket }}" + object: multipart_1 + + # Test copying multipart-uploaded object + - name: Copy object + amazon.aws.s3_object: + bucket: "{{ test_bucket }}" + mode: copy + object: multipart_1_copy + copy_src: + bucket: "{{ test_bucket }}" + object: multipart_1 + register: _copy + + - name: Ensure module reported change + ansible.builtin.assert: + that: + - _copy is changed + + - name: Retrieve object info + amazon.aws.s3_object_info: + bucket_name: "{{ test_bucket }}" + object_name: multipart_1_copy + register: obj_info + + - name: Ensure object has been created + ansible.builtin.assert: + that: + - obj_info.object_info | length == 1 + + - name: Copy object once again (idempotency) + amazon.aws.s3_object: + bucket: "{{ test_bucket }}" + mode: copy + object: multipart_1_copy + copy_src: + bucket: "{{ test_bucket }}" + object: multipart_1 + register: copy_idempotency + + - name: Ensure module did not reported change + ansible.builtin.assert: + that: + - copy_idempotency is not changed + + # Update object with metadata + - name: Copy object with metadata + amazon.aws.s3_object: + bucket: "{{ test_bucket }}" + mode: copy + object: multipart_1_copy + copy_src: + bucket: "{{ test_bucket }}" + object: multipart_1 + metadata: "{{ obj_metadata }}" + register: _copymetadata + + - name: Ensure module reported change + ansible.builtin.assert: + that: + - _copymetadata is changed + + - name: Retrieve object info + amazon.aws.s3_object_info: + bucket_name: "{{ test_bucket }}" + object_name: multipart_1_copy + register: obj_info + + - name: Ensure object has been created + ansible.builtin.assert: + that: + - obj_info.object_info | length == 1 + - obj_info.object_info.0.object_data.metadata == obj_metadata + + # Test copy with metadata (idempotency) + - name: Copy object with metadata once again (idempotency) + amazon.aws.s3_object: + bucket: "{{ test_bucket }}" + mode: copy + object: multipart_1_copy + copy_src: + bucket: "{{ test_bucket }}" + object: multipart_1 + metadata: "{{ obj_metadata }}" + register: copy_idempotency + + - name: Ensure module did not reported change + ansible.builtin.assert: + that: + - copy_idempotency is not changed + + - name: Retrieve object info + amazon.aws.s3_object_info: + bucket_name: "{{ test_bucket }}" + object_name: multipart_1_copy + register: obj_info + + - name: Ensure object has been created + ansible.builtin.assert: + that: + - obj_info.object_info | length == 1 + - obj_info.object_info.0.object_data.metadata == obj_metadata + + # Test copying multipart-uploaded object into bucket with versioning activated + # Create bucket with versioning activated + - name: Create bucket with name '{{ test_versioned_bucket }}' + amazon.aws.s3_bucket: + name: "{{ test_versioned_bucket }}" + versioning: true + state: present + + - name: Copy object into bucket with versioning activated + amazon.aws.s3_object: + bucket: "{{ test_versioned_bucket }}" + mode: copy + object: multipart_2 + copy_src: + bucket: "{{ test_bucket }}" + object: multipart_1 + register: _copy + + - name: Get objects info from bucket with versioning activated + amazon.aws.s3_object_info: + bucket_name: "{{ test_versioned_bucket }}" + object_name: multipart_2 + register: obj_info_1 + + - name: Ensure object was copied and object info contain versioning information + ansible.builtin.assert: + that: + - _copy is changed + - obj_info_1.object_info.0.object_data.version_id + + # test copy idempotency with versioned bucket + - name: Copy object into bucket with versioning activated (once again) + amazon.aws.s3_object: + bucket: "{{ test_versioned_bucket }}" + mode: copy + object: multipart_2 + copy_src: + bucket: "{{ test_bucket }}" + object: multipart_1 + register: _copy_idempotency + + - name: Get objects info from bucket with versioning activated + amazon.aws.s3_object_info: + bucket_name: "{{ test_versioned_bucket }}" + object_name: multipart_2 + register: obj_info_2 + + - name: Validate that module did not reported change and object versioned remains unchanged + ansible.builtin.assert: + that: + - _copy_idempotency is not changed + - obj_info_1.object_info.0.object_data.version_id == obj_info_2.object_info.0.object_data.version_id + + always: + - name: Delete buckets + amazon.aws.s3_bucket: + name: "{{ item }}" + state: absent + force: true + with_items: + - "{{ test_versioned_bucket }}" + - "{{ test_bucket }}" diff --git a/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_object.yml b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_object.yml index 994733d81..cfb5e13f6 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_object.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/copy_object.yml @@ -6,6 +6,9 @@ metacopy_data: name: metacopy version: "1.0.3" + another_metadata: + another: meta + mode: copy block: - name: define bucket name used for tests ansible.builtin.set_fact: @@ -211,6 +214,54 @@ - obj_info.results | selectattr('item', 'equalto', 'metacopy') | map(attribute='object_info.0.object_data.metadata') | first == metacopy_data - obj_info.results | selectattr('item', 'equalto', 'copywithmeta') | map(attribute='object_info.0.object_data.metadata') | first == withmeta_data + # Validate copy idempotency with metadata + - name: Copy same object including metadata (check_mode=true) + amazon.aws.s3_object: + bucket: "{{ bucket_name }}" + mode: copy + object: copywithmeta + copy_src: + bucket: "{{ bucket_name }}" + object: withmeta + metadata: "{{ another_metadata }}" + register: copy_with_metadata_checkmode + check_mode: true + + - name: Get objects info + amazon.aws.s3_object_info: + bucket_name: "{{ bucket_name }}" + object_name: copywithmeta + register: obj_info + + - name: Validate that objects module reported change but metadata was not updated + ansible.builtin.assert: + that: + - copy_with_metadata_checkmode is changed + - obj_info.object_info.0.object_data.metadata == withmeta_data + + - name: Copy same object including metadata + amazon.aws.s3_object: + bucket: "{{ bucket_name }}" + mode: copy + object: copywithmeta + copy_src: + bucket: "{{ bucket_name }}" + object: withmeta + metadata: "{{ another_metadata }}" + register: copy_with_metadata + + - name: Get objects info + amazon.aws.s3_object_info: + bucket_name: "{{ bucket_name }}" + object_name: copywithmeta + register: obj_info + + - name: Validate that objects module reported change and metadata was updated + ansible.builtin.assert: + that: + - copy_with_metadata is changed + - obj_info.object_info.0.object_data.metadata == another_metadata + always: - ansible.builtin.include_tasks: delete_bucket.yml with_items: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/main.yml index 7a8a585de..70041d36a 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/s3_object/tasks/main.yml @@ -1071,9 +1071,10 @@ - "'tags' in result" - (result.tags | length) == 0 - - ansible.builtin.include_tasks: copy_recursively.yml - - ansible.builtin.include_tasks: copy_object.yml - - ansible.builtin.include_tasks: copy_object_acl_disabled_bucket.yml + - ansible.builtin.include_tasks: copy_recursively.yml + - ansible.builtin.include_tasks: copy_object.yml + - ansible.builtin.include_tasks: copy_object_acl_disabled_bucket.yml + - ansible.builtin.include_tasks: copy_multipart_upload.yml always: - name: delete temporary files file: diff --git a/ansible_collections/amazon/aws/tests/integration/targets/sts_assume_role/tasks/main.yml b/ansible_collections/amazon/aws/tests/integration/targets/sts_assume_role/tasks/main.yml index 807a422c9..7fdeb71e5 100644 --- a/ansible_collections/amazon/aws/tests/integration/targets/sts_assume_role/tasks/main.yml +++ b/ansible_collections/amazon/aws/tests/integration/targets/sts_assume_role/tasks/main.yml @@ -22,7 +22,7 @@ # ============================================================ - name: create test iam role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ iam_role_name }}" assume_role_policy_document: "{{ lookup('template','policy.json.j2') }}" create_instance_profile: false @@ -247,7 +247,7 @@ # ============================================================ - name: test that assumed credentials have IAM read-only access - community.aws.iam_role: + amazon.aws.iam_role: access_key: "{{ assumed_role.sts_creds.access_key }}" secret_key: "{{ assumed_role.sts_creds.secret_key }}" session_token: "{{ assumed_role.sts_creds.session_token }}" @@ -266,7 +266,7 @@ # ============================================================ - name: test assumed role with unprivileged action - community.aws.iam_role: + amazon.aws.iam_role: access_key: "{{ assumed_role.sts_creds.access_key }}" secret_key: "{{ assumed_role.sts_creds.secret_key }}" session_token: "{{ assumed_role.sts_creds.session_token }}" @@ -295,7 +295,7 @@ # ============================================================ always: - name: delete test iam role - community.aws.iam_role: + amazon.aws.iam_role: name: "{{ iam_role_name }}" assume_role_policy_document: "{{ lookup('template','policy.json.j2') }}" delete_instance_profile: true diff --git a/ansible_collections/amazon/aws/tests/sanity/ignore-2.18.txt b/ansible_collections/amazon/aws/tests/sanity/ignore-2.18.txt new file mode 100644 index 000000000..09a7e9cbb --- /dev/null +++ b/ansible_collections/amazon/aws/tests/sanity/ignore-2.18.txt @@ -0,0 +1 @@ +plugins/modules/route53.py validate-modules:parameter-state-invalid-choice # route53_info needs improvements before we can deprecate this diff --git a/ansible_collections/amazon/aws/tests/unit/module_utils/botocore/test_is_boto3_error_code.py b/ansible_collections/amazon/aws/tests/unit/module_utils/botocore/test_is_boto3_error_code.py index 9f3e4194b..a5ce452fc 100644 --- a/ansible_collections/amazon/aws/tests/unit/module_utils/botocore/test_is_boto3_error_code.py +++ b/ansible_collections/amazon/aws/tests/unit/module_utils/botocore/test_is_boto3_error_code.py @@ -209,3 +209,71 @@ class TestIsBoto3ErrorCode: assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) assert issubclass(returned_exception, Exception) assert returned_exception.__name__ == "NeverEverRaisedException" + + def test_is_boto3_error_code_tuple__pass__client(self): + passed_exception = self._make_denied_exception() + returned_exception = is_boto3_error_code(("NotAccessDenied", "AccessDenied"), e=passed_exception) + assert isinstance(passed_exception, returned_exception) + assert issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ != "NeverEverRaisedException" + + returned_exception = is_boto3_error_code(("AccessDenied", "NotAccessDenied"), e=passed_exception) + assert isinstance(passed_exception, returned_exception) + assert issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ != "NeverEverRaisedException" + + def test_is_boto3_error_code_tuple__pass__unexpected(self): + passed_exception = self._make_unexpected_exception() + returned_exception = is_boto3_error_code(("NotAccessDenied", "AccessDenied"), e=passed_exception) + assert not isinstance(passed_exception, returned_exception) + assert not issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ == "NeverEverRaisedException" + + def test_is_boto3_error_code_tuple__pass__botocore(self): + passed_exception = self._make_botocore_exception() + returned_exception = is_boto3_error_code(("NotAccessDenied", "AccessDenied"), e=passed_exception) + assert not isinstance(passed_exception, returned_exception) + assert not issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ == "NeverEverRaisedException" + + def test_is_boto3_error_code_set__pass__client(self): + passed_exception = self._make_denied_exception() + returned_exception = is_boto3_error_code({"NotAccessDenied", "AccessDenied"}, e=passed_exception) + assert isinstance(passed_exception, returned_exception) + assert issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ != "NeverEverRaisedException" + + returned_exception = is_boto3_error_code({"AccessDenied", "NotAccessDenied"}, e=passed_exception) + assert isinstance(passed_exception, returned_exception) + assert issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ != "NeverEverRaisedException" + + def test_is_boto3_error_code_set__pass__unexpected(self): + passed_exception = self._make_unexpected_exception() + returned_exception = is_boto3_error_code({"NotAccessDenied", "AccessDenied"}, e=passed_exception) + assert not isinstance(passed_exception, returned_exception) + assert not issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ == "NeverEverRaisedException" + + def test_is_boto3_error_code_set__pass__botocore(self): + passed_exception = self._make_botocore_exception() + returned_exception = is_boto3_error_code({"NotAccessDenied", "AccessDenied"}, e=passed_exception) + assert not isinstance(passed_exception, returned_exception) + assert not issubclass(returned_exception, botocore.exceptions.ClientError) + assert not issubclass(returned_exception, botocore.exceptions.BotoCoreError) + assert issubclass(returned_exception, Exception) + assert returned_exception.__name__ == "NeverEverRaisedException" diff --git a/ansible_collections/amazon/aws/tests/unit/module_utils/iam/test_iam_resource_transforms.py b/ansible_collections/amazon/aws/tests/unit/module_utils/iam/test_iam_resource_transforms.py index 28090f993..0a6830311 100644 --- a/ansible_collections/amazon/aws/tests/unit/module_utils/iam/test_iam_resource_transforms.py +++ b/ansible_collections/amazon/aws/tests/unit/module_utils/iam/test_iam_resource_transforms.py @@ -451,10 +451,10 @@ class TestIamResourceToAnsibleDict: OUTPUT = { "arn": "arn:aws:iam::123456789012:role/ansible-test-76640355", "assume_role_policy_document": { - "statement": [ - {"action": "sts:AssumeRole", "effect": "Deny", "principal": {"service": "ec2.amazonaws.com"}} + "Statement": [ + {"Action": "sts:AssumeRole", "Effect": "Deny", "Principal": {"Service": "ec2.amazonaws.com"}} ], - "version": "2012-10-17", + "Version": "2012-10-17", }, "assume_role_policy_document_raw": { "Statement": [ diff --git a/ansible_collections/amazon/aws/tests/unit/module_utils/modules/ansible_aws_module/test_passthrough.py b/ansible_collections/amazon/aws/tests/unit/module_utils/modules/ansible_aws_module/test_passthrough.py index c61de1391..688514f59 100644 --- a/ansible_collections/amazon/aws/tests/unit/module_utils/modules/ansible_aws_module/test_passthrough.py +++ b/ansible_collections/amazon/aws/tests/unit/module_utils/modules/ansible_aws_module/test_passthrough.py @@ -70,7 +70,7 @@ def test_region(monkeypatch, stdin): aws_module = utils_module.AnsibleAWSModule(argument_spec=dict()) assert aws_module.region is sentinel.RETURNED_REGION - assert get_aws_region.call_args == call(aws_module, True) + assert get_aws_region.call_args == call(aws_module) @pytest.mark.parametrize("stdin", [{}], indirect=["stdin"]) @@ -129,7 +129,7 @@ def test_client_no_wrapper(monkeypatch, stdin): aws_module = utils_module.AnsibleAWSModule(argument_spec=dict()) assert aws_module.client(sentinel.PARAM_SERVICE) is sentinel.BOTO3_CONN - assert get_aws_connection_info.call_args == call(aws_module, boto3=True) + assert get_aws_connection_info.call_args == call(aws_module) assert boto3_conn.call_args == call( aws_module, conn_type="client", @@ -153,7 +153,7 @@ def test_client_wrapper(monkeypatch, stdin): wrapped_conn = aws_module.client(sentinel.PARAM_SERVICE, sentinel.PARAM_WRAPPER) assert wrapped_conn.client is sentinel.BOTO3_CONN assert wrapped_conn.retry is sentinel.PARAM_WRAPPER - assert get_aws_connection_info.call_args == call(aws_module, boto3=True) + assert get_aws_connection_info.call_args == call(aws_module) assert boto3_conn.call_args == call( aws_module, conn_type="client", @@ -166,7 +166,7 @@ def test_client_wrapper(monkeypatch, stdin): wrapped_conn = aws_module.client(sentinel.PARAM_SERVICE, sentinel.PARAM_WRAPPER, region=sentinel.PARAM_REGION) assert wrapped_conn.client is sentinel.BOTO3_CONN assert wrapped_conn.retry is sentinel.PARAM_WRAPPER - assert get_aws_connection_info.call_args == call(aws_module, boto3=True) + assert get_aws_connection_info.call_args == call(aws_module) assert boto3_conn.call_args == call( aws_module, conn_type="client", @@ -188,7 +188,7 @@ def test_resource(monkeypatch, stdin): aws_module = utils_module.AnsibleAWSModule(argument_spec=dict()) assert aws_module.resource(sentinel.PARAM_SERVICE) is sentinel.BOTO3_CONN - assert get_aws_connection_info.call_args == call(aws_module, boto3=True) + assert get_aws_connection_info.call_args == call(aws_module) assert boto3_conn.call_args == call( aws_module, conn_type="resource", @@ -199,7 +199,7 @@ def test_resource(monkeypatch, stdin): # Check that we can override parameters assert aws_module.resource(sentinel.PARAM_SERVICE, region=sentinel.PARAM_REGION) is sentinel.BOTO3_CONN - assert get_aws_connection_info.call_args == call(aws_module, boto3=True) + assert get_aws_connection_info.call_args == call(aws_module) assert boto3_conn.call_args == call( aws_module, conn_type="resource", diff --git a/ansible_collections/amazon/aws/tests/unit/module_utils/policy/test_sort_json_policy_dict.py b/ansible_collections/amazon/aws/tests/unit/module_utils/policy/test_sort_json_policy_dict.py deleted file mode 100644 index 8829f332c..000000000 --- a/ansible_collections/amazon/aws/tests/unit/module_utils/policy/test_sort_json_policy_dict.py +++ /dev/null @@ -1,61 +0,0 @@ -# (c) 2022 Red Hat Inc. -# -# This file is part of Ansible -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -from ansible_collections.amazon.aws.plugins.module_utils.policy import sort_json_policy_dict - - -def test_nothing_to_sort(): - simple_dict = {"key1": "a"} - nested_dict = {"key1": {"key2": "a"}} - very_nested_dict = {"key1": {"key2": {"key3": "a"}}} - assert sort_json_policy_dict(simple_dict) == simple_dict - assert sort_json_policy_dict(nested_dict) == nested_dict - assert sort_json_policy_dict(very_nested_dict) == very_nested_dict - - -def test_basic_sort(): - simple_dict = {"key1": [1, 2, 3, 4], "key2": [9, 8, 7, 6]} - sorted_dict = {"key1": [1, 2, 3, 4], "key2": [6, 7, 8, 9]} - assert sort_json_policy_dict(simple_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict - simple_dict = {"key1": ["a", "b", "c", "d"], "key2": ["z", "y", "x", "w"]} - sorted_dict = {"key1": ["a", "b", "c", "d"], "key2": ["w", "x", "y", "z"]} - assert sort_json_policy_dict(sorted_dict) == sorted_dict - - -def test_nested_list_sort(): - nested_dict = {"key1": {"key2": [9, 8, 7, 6]}} - sorted_dict = {"key1": {"key2": [6, 7, 8, 9]}} - assert sort_json_policy_dict(nested_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict - nested_dict = {"key1": {"key2": ["z", "y", "x", "w"]}} - sorted_dict = {"key1": {"key2": ["w", "x", "y", "z"]}} - assert sort_json_policy_dict(nested_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict - - -def test_nested_dict_list_sort(): - nested_dict = {"key1": {"key2": {"key3": [9, 8, 7, 6]}}} - sorted_dict = {"key1": {"key2": {"key3": [6, 7, 8, 9]}}} - assert sort_json_policy_dict(nested_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict - nested_dict = {"key1": {"key2": {"key3": ["z", "y", "x", "w"]}}} - sorted_dict = {"key1": {"key2": {"key3": ["w", "x", "y", "z"]}}} - assert sort_json_policy_dict(nested_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict - - -def test_list_of_dict_sort(): - nested_dict = {"key1": [{"key2": [4, 3, 2, 1]}, {"key3": [9, 8, 7, 6]}]} - sorted_dict = {"key1": [{"key2": [1, 2, 3, 4]}, {"key3": [6, 7, 8, 9]}]} - assert sort_json_policy_dict(nested_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict - - -def test_list_of_list_sort(): - nested_dict = {"key1": [[4, 3, 2, 1], [9, 8, 7, 6]]} - sorted_dict = {"key1": [[1, 2, 3, 4], [6, 7, 8, 9]]} - assert sort_json_policy_dict(nested_dict) == sorted_dict - assert sort_json_policy_dict(sorted_dict) == sorted_dict diff --git a/ansible_collections/amazon/aws/tests/unit/module_utils/test_elbv2.py b/ansible_collections/amazon/aws/tests/unit/module_utils/test_elbv2.py index d7293f0ce..0d2f3c153 100644 --- a/ansible_collections/amazon/aws/tests/unit/module_utils/test_elbv2.py +++ b/ansible_collections/amazon/aws/tests/unit/module_utils/test_elbv2.py @@ -6,6 +6,8 @@ from unittest.mock import MagicMock +import pytest + from ansible_collections.amazon.aws.plugins.module_utils import elbv2 one_action = [ @@ -159,3 +161,138 @@ class TestElBV2Utils: actual_elb_attributes = self.elbv2obj.get_elb_attributes() # Assert we got the expected result assert actual_elb_attributes == expected_elb_attributes + + +class TestELBListeners: + DEFAULT_PORT = 80 + DEFAULT_PROTOCOL = "TCP" + + def createListener(self, **kwargs): + result = {"Port": self.DEFAULT_PORT, "Protocol": self.DEFAULT_PROTOCOL} + if kwargs.get("port"): + result["Port"] = kwargs.get("port") + if kwargs.get("protocol"): + result["Protocol"] = kwargs.get("protocol") + if kwargs.get("certificate_arn") and kwargs.get("protocol") in ("TLS", "HTTPS"): + result["Certificates"] = [{"CertificateArn": kwargs.get("certificate_arn")}] + if kwargs.get("sslPolicy") and kwargs.get("protocol") in ("TLS", "HTTPS"): + result["SslPolicy"] = kwargs.get("sslPolicy") + if kwargs.get("alpnPolicy") and kwargs.get("protocol") == "TLS": + result["AlpnPolicy"] = kwargs.get("alpnPolicy") + return result + + @pytest.mark.parametrize("current_protocol", ["TCP", "TLS", "UDP"]) + @pytest.mark.parametrize( + "current_alpn,new_alpn", + [ + (None, "None"), + (None, "HTTP1Only"), + ("HTTP1Only", "HTTP2Only"), + ("HTTP1Only", "HTTP1Only"), + ], + ) + def test__compare_listener_alpn_policy(self, current_protocol, current_alpn, new_alpn): + current_listener = self.createListener(protocol=current_protocol, alpnPolicy=[current_alpn]) + new_listener = self.createListener(protocol="TLS", alpnPolicy=[new_alpn]) + result = None + if current_protocol != "TLS": + result = {"Protocol": "TLS"} + if new_alpn and any((current_protocol != "TLS", not current_alpn, current_alpn and current_alpn != new_alpn)): + result = result or {} + result["AlpnPolicy"] = [new_alpn] + + assert result == elbv2.ELBListeners._compare_listener(current_listener, new_listener) + + @pytest.mark.parametrize( + "current_protocol,new_protocol", + [ + ("TCP", "TCP"), + ("TLS", "HTTPS"), + ("HTTPS", "HTTPS"), + ("TLS", "TLS"), + ("HTTPS", "TLS"), + ("HTTPS", "TCP"), + ("TLS", "TCP"), + ], + ) + @pytest.mark.parametrize( + "current_ssl,new_ssl", + [ + (None, "ELBSecurityPolicy-TLS-1-0-2015-04"), + ("ELBSecurityPolicy-TLS13-1-2-Ext2-2021-06", "ELBSecurityPolicy-TLS-1-0-2015-04"), + ("ELBSecurityPolicy-TLS-1-0-2015-04", None), + ("ELBSecurityPolicy-TLS-1-0-2015-04", "ELBSecurityPolicy-TLS-1-0-2015-04"), + ], + ) + def test__compare_listener_sslpolicy(self, current_protocol, new_protocol, current_ssl, new_ssl): + current_listener = self.createListener(protocol=current_protocol, sslPolicy=current_ssl) + + new_listener = self.createListener(protocol=new_protocol, sslPolicy=new_ssl) + + expected = None + if new_protocol != current_protocol: + expected = {"Protocol": new_protocol} + if new_protocol in ("HTTPS", "TLS") and new_ssl and new_ssl != current_ssl: + expected = expected or {} + expected["SslPolicy"] = new_ssl + assert expected == elbv2.ELBListeners._compare_listener(current_listener, new_listener) + + @pytest.mark.parametrize( + "current_protocol,new_protocol", + [ + ("TCP", "TCP"), + ("TLS", "HTTPS"), + ("HTTPS", "HTTPS"), + ("TLS", "TLS"), + ("HTTPS", "TLS"), + ("HTTPS", "TCP"), + ("TLS", "TCP"), + ], + ) + @pytest.mark.parametrize( + "current_certificate,new_certificate", + [ + (None, "arn:aws:iam::012345678901:server-certificate/ansible-test-1"), + ( + "arn:aws:iam::012345678901:server-certificate/ansible-test-1", + "arn:aws:iam::012345678901:server-certificate/ansible-test-2", + ), + ("arn:aws:iam::012345678901:server-certificate/ansible-test-1", None), + ( + "arn:aws:iam::012345678901:server-certificate/ansible-test-1", + "arn:aws:iam::012345678901:server-certificate/ansible-test-1", + ), + ], + ) + def test__compare_listener_certificates(self, current_protocol, new_protocol, current_certificate, new_certificate): + current_listener = self.createListener(protocol=current_protocol, certificate_arn=current_certificate) + + new_listener = self.createListener(protocol=new_protocol, certificate_arn=new_certificate) + + expected = None + if new_protocol != current_protocol: + expected = {"Protocol": new_protocol} + if new_protocol in ("HTTPS", "TLS") and new_certificate and new_certificate != current_certificate: + expected = expected or {} + expected["Certificates"] = [{"CertificateArn": new_certificate}] + assert expected == elbv2.ELBListeners._compare_listener(current_listener, new_listener) + + @pytest.mark.parametrize( + "are_equals", + [True, False], + ) + def test__compare_listener_port(self, are_equals): + current_listener = self.createListener() + new_port = MagicMock() if not are_equals else None + new_listener = self.createListener(port=new_port) + + result = elbv2.ELBListeners._compare_listener(current_listener, new_listener) + expected = None + if not are_equals: + expected = {"Port": new_port} + assert result == expected + + def test_ensure_listeners_alpn_policy(self): + listeners = [{"Port": self.DEFAULT_PORT, "AlpnPolicy": "HTTP2Optional"}] + expected = [{"Port": self.DEFAULT_PORT, "AlpnPolicy": ["HTTP2Optional"]}] + assert expected == elbv2.ELBListeners._ensure_listeners_alpn_policy(listeners) diff --git a/ansible_collections/amazon/aws/tests/unit/plugins/modules/test_lambda_event.py b/ansible_collections/amazon/aws/tests/unit/plugins/modules/test_lambda_event.py new file mode 100644 index 000000000..c292329b4 --- /dev/null +++ b/ansible_collections/amazon/aws/tests/unit/plugins/modules/test_lambda_event.py @@ -0,0 +1,544 @@ +# +# (c) 2024 Red Hat Inc. +# +# This file is part of Ansible +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from contextlib import nullcontext as does_not_raise +from copy import deepcopy +from unittest.mock import MagicMock +from unittest.mock import patch + +import pytest + +from ansible_collections.amazon.aws.plugins.modules.lambda_event import get_qualifier +from ansible_collections.amazon.aws.plugins.modules.lambda_event import lambda_event_stream +from ansible_collections.amazon.aws.plugins.modules.lambda_event import set_default_values +from ansible_collections.amazon.aws.plugins.modules.lambda_event import validate_params + +mock_get_qualifier = "ansible_collections.amazon.aws.plugins.modules.lambda_event.get_qualifier" +mock_camel_dict_to_snake_dict = "ansible_collections.amazon.aws.plugins.modules.lambda_event.camel_dict_to_snake_dict" + + +@pytest.fixture +def ansible_aws_module(): + module = MagicMock() + module.check_mode = False + module.params = { + "state": "present", + "lambda_function_arn": None, + "event_source": "sqs", + "source_params": { + "source_arn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "batch_size": 200, + "starting_position": "LATEST", + }, + "alias": None, + "version": 0, + } + module.exit_json = MagicMock() + module.exit_json.side_effect = SystemExit(1) + module.fail_json_aws = MagicMock() + module.fail_json_aws.side_effect = SystemExit(2) + module.fail_json = MagicMock() + module.fail_json.side_effect = SystemExit(2) + module.client = MagicMock() + module.client.return_value = MagicMock() + module.boolean = MagicMock() + module.boolean.side_effect = lambda x: x.lower() in ["true", "1", "t", "y", "yes"] + return module + + +@pytest.mark.parametrize( + "module_params,expected", + [ + ({"version": 1}, "1"), + ({"alias": "ansible-test"}, "ansible-test"), + ({"version": 1, "alias": "ansible-test"}, "1"), + ({}, None), + ], +) +def test_get_qualifier(ansible_aws_module, module_params, expected): + ansible_aws_module.params.update(module_params) + assert get_qualifier(ansible_aws_module) == expected + + +@pytest.mark.parametrize( + "function_name,error_msg", + [ + ( + "invalid+function+name", + "Function name invalid+function+name is invalid. Names must contain only alphanumeric characters and hyphens.", + ), + ( + "this_invalid_function_name_has_more_than_64_character_limit_this_is_not_allowed_by_the_module", + 'Function name "this_invalid_function_name_has_more_than_64_character_limit_this_is_not_allowed_by_the_module" exceeds 64 character limit', + ), + ( + "arn:aws:lambda:us-east-2:123456789012:function:ansible-test-ansible-test-ansible-test-sqs-lambda-function:" + "ansible-test-ansible-test-ansible-test-sqs-lambda-function-alias", + 'ARN "arn:aws:lambda:us-east-2:123456789012:function:ansible-test-ansible-test-ansible-test-sqs-lambda-function:' + 'ansible-test-ansible-test-ansible-test-sqs-lambda-function-alias" exceeds 140 character limit', + ), + ], +) +def test_validate_params_function_name_errors(ansible_aws_module, function_name, error_msg): + ansible_aws_module.params.update({"lambda_function_arn": function_name}) + client = MagicMock() + client.get_function = MagicMock() + client.get_function.return_value = {} + with pytest.raises(SystemExit): + validate_params(ansible_aws_module, client) + + ansible_aws_module.fail_json.assert_called_once_with(msg=error_msg) + + +@pytest.mark.parametrize( + "qualifier", + [None, "ansible-test"], +) +@patch(mock_get_qualifier) +def test_validate_params_with_function_arn(m_get_qualifier, ansible_aws_module, qualifier): + function_name = "arn:aws:lambda:us-east-2:123456789012:function:sqs_consumer" + ansible_aws_module.params.update({"lambda_function_arn": function_name}) + m_get_qualifier.return_value = qualifier + + client = MagicMock() + client.get_function = MagicMock() + client.get_function.return_value = {} + + params = deepcopy(ansible_aws_module.params) + params["lambda_function_arn"] = f"{function_name}:{qualifier}" if qualifier else function_name + + validate_params(ansible_aws_module, client) + assert params == ansible_aws_module.params + m_get_qualifier.assert_called_once() + + +@pytest.mark.parametrize( + "qualifier", + [None, "ansible-test"], +) +@patch(mock_get_qualifier) +def test_validate_params_with_function_name(m_get_qualifier, ansible_aws_module, qualifier): + function_arn = "arn:aws:lambda:us-east-2:123456789012:function:sqs_consumer" + function_name = "sqs_consumer" + ansible_aws_module.params.update({"lambda_function_arn": function_name}) + m_get_qualifier.return_value = qualifier + + client = MagicMock() + client.get_function = MagicMock() + client.get_function.return_value = { + "Configuration": {"FunctionArn": function_arn}, + } + + params = deepcopy(ansible_aws_module.params) + params["lambda_function_arn"] = function_arn + + validate_params(ansible_aws_module, client) + + assert params == ansible_aws_module.params + m_get_qualifier.assert_called_once() + api_params = {"FunctionName": function_name} + if qualifier: + api_params.update({"Qualifier": qualifier}) + client.get_function.assert_called_once_with(**api_params) + + +EventSourceMappings = [ + { + "BatchSize": 10, + "EventSourceArn": "arn:aws:sqs:us-east-2:123456789012:sqs_consumer", + "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:sqs_consumer", + "LastModified": "2024-02-08T15:24:57.014000+01:00", + "MaximumBatchingWindowInSeconds": 0, + "State": "Enabled", + "StateTransitionReason": "USER_INITIATED", + "UUID": "3ab96d4c-b0c4-4885-87d0-f58cb9c0a4cc", + } +] + + +@pytest.mark.parametrize( + "check_mode", + [True, False], +) +@pytest.mark.parametrize( + "existing_event_source", + [True, False], +) +@patch(mock_camel_dict_to_snake_dict) +def test_lambda_event_stream_with_state_absent( + mock_camel_dict_to_snake_dict, ansible_aws_module, check_mode, existing_event_source +): + function_name = "sqs_consumer" + ansible_aws_module.params.update({"lambda_function_arn": function_name, "state": "absent"}) + ansible_aws_module.check_mode = check_mode + + client = MagicMock() + client.list_event_source_mappings = MagicMock() + + client.list_event_source_mappings.return_value = { + "EventSourceMappings": EventSourceMappings if existing_event_source else [] + } + client.delete_event_source_mapping = MagicMock() + event_source_deleted = {"msg": "event source successfully deleted."} + client.delete_event_source_mapping.return_value = event_source_deleted + mock_camel_dict_to_snake_dict.side_effect = lambda x: x + + events = [] + changed = False + result = lambda_event_stream(ansible_aws_module, client) + changed = existing_event_source + if existing_event_source: + events = EventSourceMappings + if not check_mode: + events = event_source_deleted + client.delete_event_source_mapping.assert_called_once_with(UUID=EventSourceMappings[0]["UUID"]) + else: + client.delete_event_source_mapping.assert_not_called() + assert dict(changed=changed, events=events) == result + + +def test_lambda_event_stream_create_event_missing_starting_position(ansible_aws_module): + ansible_aws_module.params = { + "state": "present", + "lambda_function_arn": "sqs_consumer", + "event_source": "stream", + "source_params": { + "source_arn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "maximum_batching_window_in_seconds": 1, + "batch_size": 200, + }, + "alias": None, + "version": 0, + } + + client = MagicMock() + client.list_event_source_mappings = MagicMock() + client.list_event_source_mappings.return_value = {"EventSourceMappings": []} + + error_message = "Source parameter 'starting_position' is required for stream event notification." + with pytest.raises(SystemExit): + lambda_event_stream(ansible_aws_module, client) + ansible_aws_module.fail_json.assert_called_once_with(msg=error_message) + + +@pytest.mark.parametrize( + "check_mode", + [True, False], +) +@pytest.mark.parametrize( + "module_params,api_params", + [ + ( + { + "state": "present", + "lambda_function_arn": "sqs_consumer", + "event_source": "stream", + "source_params": { + "source_arn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "maximum_batching_window_in_seconds": 1, + "batch_size": 250, + "starting_position": "END", + "function_response_types": ["ReportBatchItemFailures"], + }, + "alias": None, + "version": 0, + }, + { + "FunctionName": "sqs_consumer", + "EventSourceArn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "StartingPosition": "END", + "Enabled": True, + "MaximumBatchingWindowInSeconds": 1, + "BatchSize": 250, + "FunctionResponseTypes": ["ReportBatchItemFailures"], + }, + ), + ( + { + "state": "present", + "lambda_function_arn": "sqs_consumer", + "event_source": "stream", + "source_params": { + "source_arn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "maximum_batching_window_in_seconds": 1, + "batch_size": 250, + "starting_position": "END", + "function_response_types": ["ReportBatchItemFailures"], + "enabled": "no", + }, + "alias": None, + "version": 0, + }, + { + "FunctionName": "sqs_consumer", + "EventSourceArn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "StartingPosition": "END", + "Enabled": False, + "MaximumBatchingWindowInSeconds": 1, + "BatchSize": 250, + "FunctionResponseTypes": ["ReportBatchItemFailures"], + }, + ), + ( + { + "state": "present", + "lambda_function_arn": "sqs_consumer", + "event_source": "sqs", + "source_params": { + "source_arn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "maximum_batching_window_in_seconds": 1, + "batch_size": 101, + }, + "alias": None, + "version": 0, + }, + { + "FunctionName": "sqs_consumer", + "EventSourceArn": "arn:aws:sqs:us-east-2:123456789012:ansible-test-sqs", + "Enabled": True, + "MaximumBatchingWindowInSeconds": 1, + "BatchSize": 101, + }, + ), + ], +) +@patch(mock_camel_dict_to_snake_dict) +def test_lambda_event_stream_create_event( + mock_camel_dict_to_snake_dict, ansible_aws_module, check_mode, module_params, api_params +): + ansible_aws_module.params = module_params + ansible_aws_module.check_mode = check_mode + + client = MagicMock() + client.list_event_source_mappings = MagicMock() + client.list_event_source_mappings.return_value = {"EventSourceMappings": []} + + client.create_event_source_mapping = MagicMock() + event_source_created = {"msg": "event source successfully created."} + client.create_event_source_mapping.return_value = event_source_created + mock_camel_dict_to_snake_dict.side_effect = lambda x: x + + result = lambda_event_stream(ansible_aws_module, client) + + events = [] + + if not check_mode: + events = event_source_created + client.create_event_source_mapping.assert_called_once_with(**api_params) + else: + client.create_event_source_mapping.assert_not_called() + + assert dict(changed=True, events=events) == result + + +@pytest.mark.parametrize( + "check_mode", + [True, False], +) +@pytest.mark.parametrize( + "module_source_params,current_mapping,api_params", + [ + ( + {"batch_size": 100, "enabled": "false"}, + {"BatchSize": 120, "State": "Enabled"}, + {"BatchSize": 100, "Enabled": False}, + ), + ( + {"batch_size": 100, "enabled": "true"}, + {"BatchSize": 100, "State": "Enabled"}, + {}, + ), + ], +) +@patch(mock_camel_dict_to_snake_dict) +def test_lambda_event_stream_update_event( + mock_camel_dict_to_snake_dict, ansible_aws_module, check_mode, module_source_params, current_mapping, api_params +): + function_name = "ansible-test-update-event-function" + ansible_aws_module.params.update({"lambda_function_arn": function_name}) + ansible_aws_module.params["source_params"].update(module_source_params) + ansible_aws_module.check_mode = check_mode + + client = MagicMock() + client.list_event_source_mappings = MagicMock() + existing_event_source = deepcopy(EventSourceMappings) + existing_event_source[0].update(current_mapping) + client.list_event_source_mappings.return_value = {"EventSourceMappings": existing_event_source} + + client.update_event_source_mapping = MagicMock() + event_source_updated = {"msg": "event source successfully updated."} + client.update_event_source_mapping.return_value = event_source_updated + mock_camel_dict_to_snake_dict.side_effect = lambda x: x + + result = lambda_event_stream(ansible_aws_module, client) + if not api_params: + assert dict(changed=False, events=existing_event_source) == result + client.update_event_source_mapping.assert_not_called() + elif check_mode: + assert dict(changed=True, events=existing_event_source) == result + client.update_event_source_mapping.assert_not_called() + else: + api_params.update({"FunctionName": function_name, "UUID": existing_event_source[0]["UUID"]}) + assert dict(changed=True, events=event_source_updated) == result + client.update_event_source_mapping.assert_called_once_with(**api_params) + + +@pytest.mark.parametrize( + "params, expected, exception, message, source_type", + [ + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052.fifo", + "enabled": True, + "batch_size": 100, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + None, + pytest.raises(SystemExit), + "For FIFO queues the maximum batch_size is 10.", + "sqs", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052.fifo", + "enabled": True, + "batch_size": 10, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": 1, + }, + None, + pytest.raises(SystemExit), + "maximum_batching_window_in_seconds is not supported by Amazon SQS FIFO event sources.", + "sqs", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052.fifo", + "enabled": True, + "batch_size": 10, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052.fifo", + "enabled": True, + "batch_size": 10, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + does_not_raise(), + None, + "sqs", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "batch_size": 11000, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + None, + pytest.raises(SystemExit), + "For standard queue batch_size must be lower than 10000.", + "sqs", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "batch_size": 100, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "batch_size": 100, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": 1, + }, + does_not_raise(), + None, + "sqs", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "batch_size": 100, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": 1, + }, + does_not_raise(), + None, + "stream", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "starting_position": None, + "function_response_types": None, + }, + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "batch_size": 10, + "starting_position": None, + "function_response_types": None, + }, + does_not_raise(), + None, + "sqs", + ), + ( + { + "source_arn": "arn:aws:sqs:us-east-1:123456789012:ansible-test-28277052", + "enabled": True, + "batch_size": 10, + "starting_position": None, + "function_response_types": None, + "maximum_batching_window_in_seconds": None, + }, + None, + pytest.raises(SystemExit), + "batch_size for streams must be between 100 and 10000", + "stream", + ), + ], +) +def test__set_default_values(params, expected, exception, message, source_type): + result = None + module = MagicMock() + module.check_mode = False + module.params = { + "event_source": source_type, + "source_params": params, + } + module.fail_json = MagicMock() + module.fail_json.side_effect = SystemExit(message) + with exception as e: + result = set_default_values(module, params) + assert message is None or message in str(e) + if expected is not None: + assert result == expected |