Repository: ansible-collections/amazon.aws

Issue:
elb_application_lb does not modify attributes on creation
### Summary

On creation of Application Load Balancer with elb_application_lb, it does not set attributes.
I have to run the same module a second time to get attributes set.

Example of attribute : `idle_timeout`

### Issue Type

Bug Report

### Component Name

elb_application_lb

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] (/usr/bin/python)
  jinja version = 3.1.2
  libyaml = True
```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list

# /usr/local/lib/python3.9/dist-packages/ansible_collections
Collection                    Version
----------------------------- -------
amazon.aws                    5.4.0
ansible.netcommon             4.1.0
ansible.posix                 1.5.2
ansible.utils                 2.9.0
ansible.windows               1.13.0
arista.eos                    6.0.1
awx.awx                       21.14.0
azure.azcollection            1.15.0
check_point.mgmt              4.0.0
chocolatey.chocolatey         1.4.0
cisco.aci                     2.6.0
cisco.asa                     4.0.0
cisco.dnac                    6.7.1
cisco.intersight              1.0.27
cisco.ios                     4.5.0
cisco.iosxr                   4.1.0
cisco.ise                     2.5.12
cisco.meraki                  2.15.1
cisco.mso                     2.4.0
cisco.nso                     1.0.3
cisco.nxos                    4.3.0
cisco.ucs                     1.8.0
cloud.common                  2.1.3
cloudscale_ch.cloud           2.2.4
community.aws                 5.4.0
community.azure               2.0.0
community.ciscosmb            1.0.5
community.crypto              2.12.0
community.digitalocean        1.23.0
community.dns                 2.5.3
community.docker              3.4.3
community.fortios             1.0.0
community.general             6.6.0
community.google              1.0.0
community.grafana             1.5.4
community.hashi_vault         4.2.0
community.hrobot              1.8.0
community.libvirt             1.2.0
community.mongodb             1.5.2
community.mysql               3.6.0
community.network             5.0.0
community.okd                 2.3.0
community.postgresql          2.3.2
community.proxysql            1.5.1
community.rabbitmq            1.2.3
community.routeros            2.8.0
community.sap                 1.0.0
community.sap_libs            1.4.1
community.skydive             1.0.0
community.sops                1.6.1
community.vmware              3.5.0
community.windows             1.12.0
community.zabbix              1.9.3
containers.podman             1.10.1
cyberark.conjur               1.2.0
cyberark.pas                  1.0.17
dellemc.enterprise_sonic      2.0.0
dellemc.openmanage            6.3.0
dellemc.os10                  1.1.1
dellemc.os6                   1.0.7
dellemc.os9                   1.0.4
dellemc.powerflex             1.6.0
dellemc.unity                 1.6.0
f5networks.f5_modules         1.23.0
fortinet.fortimanager         2.1.7
fortinet.fortios              2.2.3
frr.frr                       2.0.2
gluster.gluster               1.0.2
google.cloud                  1.1.3
grafana.grafana               1.1.1
hetzner.hcloud                1.11.0
hpe.nimble                    1.1.4
ibm.qradar                    2.1.0
ibm.spectrum_virtualize       1.11.0
infinidat.infinibox           1.3.12
infoblox.nios_modules         1.4.1
inspur.ispim                  1.3.0
inspur.sm                     2.3.0
junipernetworks.junos         4.1.0
kubernetes.core               2.4.0
lowlydba.sqlserver            1.3.1
mellanox.onyx                 1.0.0
microsoft.ad                  1.0.0
netapp.aws                    21.7.0
netapp.azure                  21.10.0
netapp.cloudmanager           21.22.0
netapp.elementsw              21.7.0
netapp.ontap                  22.5.0
netapp.storagegrid            21.11.1
netapp.um_info                21.8.0
netapp_eseries.santricity     1.4.0
netbox.netbox                 3.12.0
ngine_io.cloudstack           2.3.0
ngine_io.exoscale             1.0.0
ngine_io.vultr                1.1.3
openstack.cloud               1.10.0
openvswitch.openvswitch       2.1.0
ovirt.ovirt                   2.4.1
purestorage.flasharray        1.17.2
purestorage.flashblade        1.11.0
purestorage.fusion            1.4.2
sensu.sensu_go                1.13.2
splunk.es                     2.1.0
t_systems_mms.icinga_director 1.32.2
theforeman.foreman            3.10.0
vmware.vmware_rest            2.3.1
vultr.cloud                   1.7.0
vyos.vyos                     4.0.2
wti.remote                    1.0.4
```


### AWS SDK versions

```console (paste below)
$ pip show boto boto3 botocore
WARNING: Package(s) not found: boto
Name: boto3
Version: 1.26.124
Summary: The AWS SDK for Python
Home-page: https://github.com/boto/boto3
Author: Amazon Web Services
Author-email:
License: Apache License 2.0
Location: /usr/local/lib/python3.9/dist-packages
Requires: botocore, jmespath, s3transfer
Required-by: aws-sam-cli, aws-sam-translator, serverlessrepo
---
Name: botocore
Version: 1.29.124
Summary: Low-level, data-driven core of boto 3.
Home-page: https://github.com/boto/botocore
Author: Amazon Web Services
Author-email:
License: Apache License 2.0
Location: /usr/local/lib/python3.9/dist-packages
Requires: jmespath, python-dateutil, urllib3
Required-by: boto3, s3transfer
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
CONFIG_FILE() = None
```


### OS / Environment

RHEL 7

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
---
- hosts: localhost
  tasks:
    - amazon.aws.elb_application_lb:
        name: myalb
        security_groups:
          - sg-0e52fd4c1fbfff66f
        subnets:
          - subnet-af8243cb
          - subnet-dffffaaf
        scheme: internal
        idle_timeout: 120
```


### Expected Results

I expected that `idle_timeout` is set to 120 but it still set to default value `60`

```
 "idle_timeout_timeout_seconds": "120",
```

Full:
```
[...]
TASK [amazon.aws.elb_application_lb] *****************************************************************************************************************************************************************************
task path: /test.yml:5
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912 `" && echo ansible-tmp-1683125471.952906-552-23560833760912="` echo /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912 `" ) && sleep 0'
Using module file /usr/local/lib/python3.9/dist-packages/ansible_collections/amazon/aws/plugins/modules/elb_application_lb.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-5116wxppa0t/tmpou0kgexj TO /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912/AnsiballZ_elb_application_lb.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912/ /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912/AnsiballZ_elb_application_lb.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912/AnsiballZ_elb_application_lb.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1683125471.952906-552-23560833760912/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "access_logs_s3_bucket": "",
    "access_logs_s3_enabled": "false",
    "access_logs_s3_prefix": "",
    "availability_zones": [
        {
            "load_balancer_addresses": [],
            "subnet_id": "subnet-af8243cb",
            "zone_name": "eu-west-1a"
        },
        {
            "load_balancer_addresses": [],
            "subnet_id": "subnet-d914faaf",
            "zone_name": "eu-west-1b"
        }
    ],
    "canonical_hosted_zone_id": "Z32O12XQLNTSW2",
    "changed": true,
    "created_time": "2023-05-03T14:48:48.320000+00:00",
    "deletion_protection_enabled": "false",
    "dns_name": "internal-myalb-594562057.eu-west-1.elb.amazonaws.com",
    "idle_timeout_timeout_seconds": "120",
    "invocation": {
        "module_args": {
            "access_key": null,
            "access_logs_enabled": null,
            "access_logs_s3_bucket": null,
            "access_logs_s3_prefix": null,
            "aws_ca_bundle": null,
            "aws_config": null,
            "debug_botocore_endpoint_logs": false,
            "deletion_protection": null,
            "endpoint_url": null,
            "http2": null,
            "http_desync_mitigation_mode": null,
            "http_drop_invalid_header_fields": null,
            "http_x_amzn_tls_version_and_cipher_suite": null,
            "http_xff_client_port": null,
            "idle_timeout": 120,
            "ip_address_type": null,
            "listeners": null,
            "name": "myalb",
            "profile": null,
            "purge_listeners": true,
            "purge_rules": true,
            "purge_tags": true,
            "region": null,
            "scheme": "internal",
            "secret_key": null,
            "security_groups": [
                "sg-0e52fd4c1fb8f066f"
            ],
            "session_token": null,
            "state": "present",
            "subnets": [
                "subnet-af8243cb",
                "subnet-d914faaf"
            ],
            "tags": null,
            "validate_certs": true,
            "waf_fail_open": null,
            "wait": false,
            "wait_timeout": null
        }
    },
    "ip_address_type": "ipv4",
    "listeners": [],
    "load_balancer_arn": "arn:aws:elasticloadbalancing:eu-west-1:277969949725:loadbalancer/app/myalb/bd804726f6827fea",
    "load_balancer_name": "myalb",
    "load_balancing_cross_zone_enabled": "true",
    "routing_http2_enabled": "true",
    "routing_http_desync_mitigation_mode": "defensive",
    "routing_http_drop_invalid_header_fields_enabled": "false",
    "routing_http_preserve_host_header_enabled": "false",
    "routing_http_x_amzn_tls_version_and_cipher_suite_enabled": "false",
    "routing_http_xff_client_port_enabled": "false",
    "routing_http_xff_header_processing_mode": "append",
    "scheme": "internal",
    "security_groups": [
        "sg-0e52fd4c1fb8f066f"
    ],
    "state": {
        "code": "active"
    },
    "tags": {},
    "type": "application",
    "vpc_id": "vpc-63091d06",
    "waf_fail_open_enabled": "false"
}
```

### Actual Results

When I run this playbook when ALB does not exists (creation)

```console
    "idle_timeout_timeout_seconds": "60",
```

```console (paste below)
[...]
TASK [amazon.aws.elb_application_lb] *****************************************************************************************************************************************************************************
task path: /test.yml:5
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656 `" && echo ansible-tmp-1683125326.792243-484-245035774975656="` echo /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656 `" ) && sleep 0'
Using module file /usr/local/lib/python3.9/dist-packages/ansible_collections/amazon/aws/plugins/modules/elb_application_lb.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-4431qcb255m/tmpq7pzc4mc TO /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656/AnsiballZ_elb_application_lb.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656/ /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656/AnsiballZ_elb_application_lb.py&& sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656/AnsiballZ_elb_application_lb.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1683125326.792243-484-245035774975656/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "access_logs_s3_bucket": "",
    "access_logs_s3_enabled": "false",
    "access_logs_s3_prefix": "",
    "availability_zones": [
        {
            "load_balancer_addresses": [],
            "subnet_id": "subnet-af8243cb",
            "zone_name": "eu-west-1a"
        },
        {
            "load_balancer_addresses": [],
            "subnet_id": "subnet-d914faaf",
            "zone_name": "eu-west-1b"
        }
    ],
    "canonical_hosted_zone_id": "Z32O12XQLNTSW2",
    "changed": true,
    "created_time": "2023-05-03T14:48:48.320000+00:00",
    "deletion_protection_enabled": "false",
    "dns_name": "internal-myalb-594562057.eu-west-1.elb.amazonaws.com",
    "idle_timeout_timeout_seconds": "60",
    "invocation": {
        "module_args": {
            "access_key": null,
            "access_logs_enabled": null,
            "access_logs_s3_bucket": null,
            "access_logs_s3_prefix": null,
            "aws_ca_bundle": null,
            "aws_config": null,
            "debug_botocore_endpoint_logs": false,
            "deletion_protection": null,
            "endpoint_url": null,
            "http2": null,
            "http_desync_mitigation_mode": null,
            "http_drop_invalid_header_fields": null,
            "http_x_amzn_tls_version_and_cipher_suite": null,
            "http_xff_client_port": null,
            "idle_timeout": 120,
            "ip_address_type": null,
            "listeners": null,
            "name": "myalb",
            "profile": null,
            "purge_listeners": true,
            "purge_rules": true,
            "purge_tags": true,
            "region": null,
            "scheme": "internal",
            "secret_key": null,
            "security_groups": [
                "sg-0e52fd4c1fb8f066f"
            ],
            "session_token": null,
            "state": "present",
            "subnets": [
                "subnet-af8243cb",
                "subnet-d914faaf"
            ],
            "tags": null,
            "validate_certs": true,
            "waf_fail_open": null,
            "wait": false,
            "wait_timeout": null
        }
    },
    "ip_address_type": "ipv4",
    "listeners": [],
    "load_balancer_arn": "arn:aws:elasticloadbalancing:eu-west-1:277969949725:loadbalancer/app/myalb/bd804726f6827fea",
    "load_balancer_name": "myalb",
    "load_balancing_cross_zone_enabled": "true",
    "routing_http2_enabled": "true",
    "routing_http_desync_mitigation_mode": "defensive",
    "routing_http_drop_invalid_header_fields_enabled": "false",
    "routing_http_preserve_host_header_enabled": "false",
    "routing_http_x_amzn_tls_version_and_cipher_suite_enabled": "false",
    "routing_http_xff_client_port_enabled": "false",
    "routing_http_xff_header_processing_mode": "append",
    "scheme": "internal",
    "security_groups": [
        "sg-0e52fd4c1fb8f066f"
    ],
    "state": {
        "code": "provisioning"
    },
    "tags": {},
    "type": "application",
    "vpc_id": "vpc-63091d06",
    "waf_fail_open_enabled": "false"
}
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:

Resolving patch:
diff --git a/plugins/modules/elb_application_lb.py b/plugins/modules/elb_application_lb.py
--- a/plugins/modules/elb_application_lb.py
+++ b/plugins/modules/elb_application_lb.py
@@ -614,6 +614,10 @@ def create_or_update_alb(alb_obj):
             alb_obj.module.exit_json(changed=True, msg="Would have created ALB if not in check mode.")
         alb_obj.create_elb()
 
+        # Add ALB attributes
+        alb_obj.update_elb_attributes()
+        alb_obj.modify_elb_attributes()
+
     # Listeners
     listeners_obj = ELBListeners(alb_obj.connection, alb_obj.module, alb_obj.elb["LoadBalancerArn"])
     listeners_to_add, listeners_to_modify, listeners_to_delete = listeners_obj.compare_listeners()


Test patch:
diff --git a/tests/integration/targets/elb_application_lb/defaults/main.yml b/tests/integration/targets/elb_application_lb/defaults/main.yml
--- a/tests/integration/targets/elb_application_lb/defaults/main.yml
+++ b/tests/integration/targets/elb_application_lb/defaults/main.yml
@@ -2,9 +2,27 @@
 
 resource_short: "{{ '%0.8x'%((16**8) | random(seed=resource_prefix)) }}"
 alb_name: alb-test-{{ resource_short }}
+alb_2_name: alb-test-2-{{ resource_short }}
 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
 private_subnet_cidr_1: 10.{{ 256 | random(seed=resource_prefix) }}.1.0/24
 private_subnet_cidr_2: 10.{{ 256 | random(seed=resource_prefix) }}.2.0/24
 public_subnet_cidr_1: 10.{{ 256 | random(seed=resource_prefix) }}.3.0/24
 public_subnet_cidr_2: 10.{{ 256 | random(seed=resource_prefix) }}.4.0/24
+s3_bucket_name: alb-test-{{ resource_short }}
+
+# Amazon's SDKs don't provide the list of account ID's.  Amazon only provide a
+# web page.  If you want to run the tests outside the US regions you'll need to
+# update this.
+# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/enable-access-logging.html
+elb_access_log_account_id_map:
+  us-east-1: "127311923021"
+  us-east-2: "033677994240"
+  us-west-1: "027434742980"
+  us-west-2: "797873946194"
+  us-gov-east-1: "190560391635"
+  us-gov-west-1: "048591011584"
+
+
+elb_account_id: '{{ elb_access_log_account_id_map[aws_region] }}'
diff --git a/tests/integration/targets/elb_application_lb/tasks/main.yml b/tests/integration/targets/elb_application_lb/tasks/main.yml
--- a/tests/integration/targets/elb_application_lb/tasks/main.yml
+++ b/tests/integration/targets/elb_application_lb/tasks/main.yml
@@ -115,6 +115,27 @@
       vpc_id: '{{ vpc_id }}'
       state: present
     register: tg
+  - name: Create a second target group for testing
+    community.aws.elb_target_group:
+      name: '{{ tg_2_name }}'
+      protocol: http
+      port: 80
+      vpc_id: '{{ vpc_id }}'
+      state: present
+    register: tg_2
+  - name: Get ARN of calling user
+    amazon.aws.aws_caller_info:
+    register: aws_caller_info
+  - name: Register account id
+    ansible.builtin.set_fact:
+      aws_account: "{{ aws_caller_info.account }}"
+  - name: Create S3 bucket for testing
+    amazon.aws.s3_bucket:
+      name: "{{ s3_bucket_name }}"
+      state: present
+      encryption: "aws:kms"
+      policy: "{{ lookup('template', 'policy.json') }}"
+
   - name: Create an ALB (invalid - SslPolicy is required when Protocol == HTTPS)
     elb_application_lb:
       name: '{{ alb_name }}'
@@ -270,6 +291,157 @@
 
     # ------------------------------------------------------------------------------------------
 
+  - name: Create an ALB with attributes - check_mode
+    amazon.aws.elb_application_lb:
+      name: '{{ alb_2_name }}'
+      subnets: '{{ public_subnets }}'
+      security_groups: '{{ sec_group.group_id }}'
+      state: present
+      listeners:
+        - Protocol: HTTP
+          Port: 80
+          DefaultActions:
+            - Type: forward
+              TargetGroupName: '{{ tg_2_name }}'
+      access_logs_enabled: true
+      access_logs_s3_bucket: "{{ s3_bucket_name }}"
+      access_logs_s3_prefix: "alb-logs"
+      ip_address_type: dualstack
+      http2: false
+      http_desync_mitigation_mode: monitor
+      http_drop_invalid_header_fields: true
+      http_x_amzn_tls_version_and_cipher_suite: true
+      http_xff_client_port: true
+      waf_fail_open: true
+    register: alb_2
+    check_mode: true
+
+  - name: Verify check mode response
+    ansible.builtin.assert:
+      that:
+        - alb_2 is changed
+        - alb_2.msg is match('Would have created ALB if not in check mode.')
+
+  - name: Create an ALB with attributes
+    amazon.aws.elb_application_lb:
+      name: '{{ alb_2_name }}'
+      subnets: '{{ public_subnets }}'
+      security_groups: '{{ sec_group.group_id }}'
+      state: present
+      listeners:
+        - Protocol: HTTP
+          Port: 80
+          DefaultActions:
+            - Type: forward
+              TargetGroupName: '{{ tg_2_name }}'
+      access_logs_enabled: true
+      access_logs_s3_bucket: "{{ s3_bucket_name }}"
+      access_logs_s3_prefix: "alb-logs"
+      http2: false
+      http_desync_mitigation_mode: monitor
+      http_drop_invalid_header_fields: true
+      http_x_amzn_tls_version_and_cipher_suite: true
+      http_xff_client_port: true
+      idle_timeout: 120
+      ip_address_type: dualstack
+      waf_fail_open: true
+    register: alb_2
+
+  - name: Verify ALB was created with correct attributes
+    ansible.builtin.assert:
+      that:
+        - alb_2 is changed
+        - alb_2.listeners[0].rules | length == 1
+        - alb_2.security_groups | length == 1
+        - alb_2.security_groups[0] == sec_group.group_id
+        - alb_2.ip_address_type == 'dualstack'
+        - alb_2.access_logs_s3_enabled | bool
+        - alb_2.access_logs_s3_bucket == "{{ s3_bucket_name }}"
+        - alb_2.access_logs_s3_prefix == "alb-logs"
+        - not alb_2.routing_http2_enabled | bool
+        - alb_2.routing_http_desync_mitigation_mode == 'monitor'
+        - alb_2.routing_http_drop_invalid_header_fields_enabled | bool
+        - alb_2.routing_http_x_amzn_tls_version_and_cipher_suite_enabled | bool
+        - alb_2.routing_http_xff_client_port_enabled | bool
+        - alb_2.idle_timeout_timeout_seconds == "120"
+        - alb_2.waf_fail_open_enabled | bool
+
+  - name: Create an ALB with attributes (idempotence) - check_mode
+    amazon.aws.elb_application_lb:
+      name: '{{ alb_2_name }}'
+      subnets: '{{ public_subnets }}'
+      security_groups: '{{ sec_group.group_id }}'
+      state: present
+      listeners:
+        - Protocol: HTTP
+          Port: 80
+          DefaultActions:
+            - Type: forward
+              TargetGroupName: '{{ tg_2_name }}'
+      access_logs_enabled: true
+      access_logs_s3_bucket: "{{ s3_bucket_name }}"
+      access_logs_s3_prefix: "alb-logs"
+      ip_address_type: dualstack
+      http2: false
+      http_desync_mitigation_mode: monitor
+      http_drop_invalid_header_fields: true
+      http_x_amzn_tls_version_and_cipher_suite: true
+      http_xff_client_port: true
+      waf_fail_open: true
+    register: alb_2
+    check_mode: true
+
+  - name: Verify idempotence check mode response
+    ansible.builtin.assert:
+      that:
+        - alb_2 is not changed
+        - alb_2.msg is match('IN CHECK MODE - no changes to make to ALB specified.')
+
+  - name: Create an ALB with attributes (idempotence)
+    amazon.aws.elb_application_lb:
+      name: '{{ alb_2_name }}'
+      subnets: '{{ public_subnets }}'
+      security_groups: '{{ sec_group.group_id }}'
+      state: present
+      listeners:
+        - Protocol: HTTP
+          Port: 80
+          DefaultActions:
+            - Type: forward
+              TargetGroupName: '{{ tg_2_name }}'
+      access_logs_enabled: true
+      access_logs_s3_bucket: "{{ s3_bucket_name }}"
+      access_logs_s3_prefix: "alb-logs"
+      ip_address_type: dualstack
+      http2: false
+      http_desync_mitigation_mode: monitor
+      http_drop_invalid_header_fields: true
+      http_x_amzn_tls_version_and_cipher_suite: true
+      http_xff_client_port: true
+      waf_fail_open: true
+    register: alb_2
+
+  - name: Verify ALB was not changed
+    ansible.builtin.assert:
+      that:
+        - alb_2 is not changed
+        - alb_2.listeners[0].rules | length == 1
+        - alb_2.security_groups | length == 1
+        - alb_2.security_groups[0] == sec_group.group_id
+        - alb_2.ip_address_type == 'dualstack'
+        - alb_2.access_logs_s3_enabled | bool
+        - alb_2.access_logs_s3_bucket == "{{ s3_bucket_name }}"
+        - alb_2.access_logs_s3_prefix == "alb-logs"
+        - not alb_2.routing_http2_enabled | bool
+        - alb_2.routing_http_desync_mitigation_mode == 'monitor'
+        - alb_2.routing_http_drop_invalid_header_fields_enabled | bool
+        - alb_2.routing_http_x_amzn_tls_version_and_cipher_suite_enabled | bool
+        - alb_2.routing_http_xff_client_port_enabled | bool
+        - alb_2.idle_timeout_timeout_seconds == "120"
+        - alb_2.waf_fail_open_enabled | bool
+
+    # ------------------------------------------------------------------------------------------
+
   - name: Update an ALB with ip address type - check_mode
     elb_application_lb:
       name: '{{ alb_name }}'
@@ -1275,6 +1447,13 @@
       wait: true
       wait_timeout: 600
     ignore_errors: true
+  - name: Destroy ALB 2
+    amazon.aws.elb_application_lb:
+      name: '{{ alb_2_name }}'
+      state: absent
+      wait: true
+      wait_timeout: 600
+    ignore_errors: true
   - name: Destroy target group if it was created
     elb_target_group:
       name: '{{ tg_name }}'
@@ -1290,6 +1469,21 @@
     until: remove_tg is success
     when: tg is defined
     ignore_errors: true
+  - name: Destroy target group 2 if it was created
+    community.aws.elb_target_group:
+      name: '{{ tg_2_name }}'
+      protocol: http
+      port: 80
+      vpc_id: '{{ vpc_id }}'
+      state: absent
+      wait: true
+      wait_timeout: 600
+    register: remove_tg_2
+    retries: 5
+    delay: 3
+    until: remove_tg_2 is success
+    when: tg_2 is defined
+    ignore_errors: true
   - name: Destroy sec groups
     ec2_security_group:
       name: '{{ item }}'
@@ -1352,3 +1546,13 @@
     delay: 5
     until: remove_vpc is success
     ignore_errors: true
+  - name: Destroy ELB acccess log test file
+    amazon.aws.s3_object:
+      bucket: "{{ s3_bucket_name }}"
+      mode: delobj
+      object: "alb-logs/AWSLogs/{{ aws_account }}/ELBAccessLogTestFile"
+  - name: Destroy S3 bucket
+    amazon.aws.s3_bucket:
+      name: "{{ s3_bucket_name }}"
+      state: absent
+      force: true
diff --git a/tests/integration/targets/elb_application_lb/templates/policy.json b/tests/integration/targets/elb_application_lb/templates/policy.json
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/elb_application_lb/templates/policy.json
@@ -0,0 +1,13 @@
+{
+    "Version": "2012-10-17",
+    "Statement": [
+        {
+            "Effect": "Allow",
+            "Principal": {
+                "AWS": "arn:aws:iam::{{ elb_account_id}}:root"
+            },
+            "Action": "s3:PutObject",
+            "Resource": "arn:aws:s3:::{{ s3_bucket_name }}/alb-logs/AWSLogs/{{ aws_account }}/*"
+        }
+    ]
+}