Repository: ansible-collections/community.aws

Issue:
The EKS cluster security token must be between 33 and 126 characters long...forcing the length of "name" parameter for aws_eks_cluster module to succeed.
### Summary

When leveraging a role that uses the aws_eks_cluster module, I encountered a repeated error about security token length. The issue was 'resolved' when I passed in a very long "name" parameter.

### Issue Type

Bug Report

### Component Name

aws_eks_cluster

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.11.4] 
  config file = None
  configured module search path = ['/Users/jdelapor/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Library/Python/3.8/site-packages/ansible
  ansible collection location = /Users/jdelapor/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.8.2 (default, Dec 21 2020, 15:06:04) [Clang 12.0.0 (clang-1200.0.32.29)]
  jinja version = 3.0.1
  libyaml = True
```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list
# /Library/Python/3.8/site-packages/ansible_collections
Collection                    Version
----------------------------- -------
amazon.aws                    1.5.0  
ansible.netcommon             2.3.0  
ansible.posix                 1.2.0  
ansible.utils                 2.3.1  
ansible.windows               1.7.2  
arista.eos                    2.2.0  
awx.awx                       19.2.2 
azure.azcollection            1.8.0  
check_point.mgmt              2.0.0  
chocolatey.chocolatey         1.1.0  
cisco.aci                     2.0.0  
cisco.asa                     2.0.2  
cisco.intersight              1.0.16 
cisco.ios                     2.3.1  
cisco.iosxr                   2.4.0  
cisco.meraki                  2.4.2  
cisco.mso                     1.2.0  
cisco.nso                     1.0.3  
cisco.nxos                    2.5.0  
cisco.ucs                     1.6.0  
cloudscale_ch.cloud           2.2.0  
community.aws                 1.5.0  
community.azure               1.0.0  
community.crypto              1.8.0  
community.digitalocean        1.8.0  
community.docker              1.9.0  
community.fortios             1.0.0  
community.general             3.5.0  
community.google              1.0.0  
community.grafana             1.2.1  
community.hashi_vault         1.3.2  
community.hrobot              1.1.1  
community.kubernetes          1.2.1  
community.kubevirt            1.0.0  
community.libvirt             1.0.2  
community.mongodb             1.3.0  
community.mysql               2.1.0  
community.network             3.0.0  
community.okd                 1.1.2  
community.postgresql          1.4.0  
community.proxysql            1.1.0  
community.rabbitmq            1.1.0  
community.routeros            1.2.0  
community.skydive             1.0.0  
community.sops                1.1.0  
community.vmware              1.12.0 
community.windows             1.6.0  
community.zabbix              1.4.0  
containers.podman             1.6.2  
cyberark.conjur               1.1.0  
cyberark.pas                  1.0.7  
dellemc.enterprise_sonic      1.1.0  
dellemc.openmanage            3.6.0  
dellemc.os10                  1.1.1  
dellemc.os6                   1.0.7  
dellemc.os9                   1.0.4  
f5networks.f5_modules         1.11.0 
fortinet.fortimanager         2.1.3  
fortinet.fortios              2.1.2  
frr.frr                       1.0.3  
gluster.gluster               1.0.1  
google.cloud                  1.0.2  
hetzner.hcloud                1.4.4  
hpe.nimble                    1.1.3  
ibm.qradar                    1.0.3  
infinidat.infinibox           1.2.4  
inspur.sm                     1.2.0  
junipernetworks.junos         2.4.0  
kubernetes.core               1.2.1  
mellanox.onyx                 1.0.0  
netapp.aws                    21.6.0 
netapp.azure                  21.8.1 
netapp.cloudmanager           21.9.0 
netapp.elementsw              21.6.1 
netapp.ontap                  21.9.0 
netapp.um_info                21.7.0 
netapp_eseries.santricity     1.2.13 
netbox.netbox                 3.1.1  
ngine_io.cloudstack           2.1.0  
ngine_io.exoscale             1.0.0  
ngine_io.vultr                1.1.0  
openstack.cloud               1.5.0  
openvswitch.openvswitch       2.0.0  
ovirt.ovirt                   1.5.4  
purestorage.flasharray        1.10.0 
purestorage.flashblade        1.6.0  
sensu.sensu_go                1.11.1 
servicenow.servicenow         1.0.6  
splunk.es                     1.0.2  
t_systems_mms.icinga_director 1.20.0 
theforeman.foreman            2.1.2  
vyos.vyos                     2.5.0  
wti.remote                    1.0.1  

# /Users/jdelapor/.ansible/collections/ansible_collections
Collection         Version
------------------ -------
amazon.aws         1.5.0  
azure.azcollection 1.8.0  
community.aws      1.5.0  
google.cloud       1.0.2  
kubernetes.core    2.1.1  
```


### AWS SDK versions

```console (paste below)
$ pip show boto boto3 botocore
Name: boto
Version: 2.49.0
Summary: Amazon Web Services Library
Home-page: https://github.com/boto/boto/
Author: Mitch Garnaat
Author-email: mitch@garnaat.com
License: MIT
Location: /Users/jdelapor/Library/Python/3.8/lib/python/site-packages
Requires: 
Required-by: 
---
Name: boto3
Version: 1.20.17
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: /Users/jdelapor/Library/Python/3.8/lib/python/site-packages
Requires: s3transfer, jmespath, botocore
Required-by: 
---
Name: botocore
Version: 1.23.17
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: /Users/jdelapor/Library/Python/3.8/lib/python/site-packages
Requires: jmespath, python-dateutil, urllib3
Required-by: s3transfer, boto3, awscli

```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
null
```


### OS / Environment

EKS

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
Running the playbook from https://github.com/nleiva/ansible-kubernetes, it fails at this task if I use a short cluster name:

```yaml (paste below)
- name: Create EKS cluster
  community.aws.aws_eks_cluster:
    name: "{{ cluster_name }}"
    version: "{{ k8s_version }}"
    role_arn: "{{ eks_role.arn }}"
    wait: true
    wait_timeout: "{{ eks_timeout }}"
    region: "{{ aws_region }}"
    subnets:
      - "{{ create_subnet_1.subnet.id }}"
      - "{{ create_subnet_2.subnet.id }}"
    security_groups: "{{ ec2_resource_prefix }}-SG"
  register: create_eks
```

It fails when I use this command to run the playbook:
```console
ansible-playbook main.yml -vvv --extra-vars "cloud_provider=aws my_resource_prefix=jdelaportek8s my_cluster_name=jdelaportek81"
```

It succeeds when I run the playbook with this command:
```console
ansible-playbook main.yml -vvv --extra-vars "cloud_provider=aws my_resource_prefix=jdelaportek8s my_cluster_name=jdelaportek81isthislongenoughforyouyetbotocore"
```




### Expected Results

I expected a cluster to be created based on any nominally normal cluster name length. There is no length restriction mentioned in the aws_eks_cluster module. The examples show a 10-char name length, which would be too short to succeed.

### Actual Results

Using the aws eks role located here: https://github.com/nleiva/ansible-kubernetes

```console (paste below)
ansible-playbook main.yml -v --extra-vars "cloud_provider=aws my_resource_prefix=jdelaportek8s my_cluster_name=jdelaportek81"

---- truncated ----
TASK [aws_create_eks : Provision EKS Cluster tasks] **********************************************************************************************************************************************
included: /Users/jdelapor/gitstuff/ansible-kubernetes/roles/aws_create_eks/tasks/create_eks.yml for localhost

TASK [aws_create_eks : Create EKS cluster] *******************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: botocore.errorfactory.InvalidParameterException: An error occurred (InvalidParameterException) when calling the CreateCluster operation: The client request token parameter must be between 33 and 126 characters.
fatal: [localhost]: FAILED! => {
"boto3_version": "1.20.17",
"botocore_version": "1.23.17",
"changed": false,
"error": {
"code": "InvalidParameterException",
"message": "The client request token parameter must be between 33 and 126 characters."
},
"message": "The client request token parameter must be between 33 and 126 characters.",
"response_metadata": {
"http_headers": {
"access-control-allow-headers": ",Authorization,Date,X-Amz-Date,X-Amz-Security-Token,X-Amz-Target,content-type,x-amz-content-sha256,x-amz-user-agent,x-amzn-platform-id,x-amzn-trace-id",
"access-control-allow-methods": "GET,HEAD,PUT,POST,DELETE,OPTIONS",
"access-control-allow-origin": "",
"access-control-expose-headers": "x-amzn-errortype,x-amzn-errormessage,x-amzn-trace-id,x-amzn-requestid,x-amz-apigw-id,date",
"connection": "keep-alive",
"content-length": "196",
"content-type": "application/json",
"date": "Wed, 01 Dec 2021 22:55:01 GMT",
"x-amz-apigw-id": "JsSC1EIDIAMFT-g=",
"x-amzn-errortype": "InvalidParameterException",
"x-amzn-requestid": "d6ee553b-0e0f-4b68-81ff-e1c434fde032",
"x-amzn-trace-id": "Root=1-61a7fd45-71e15c9a2fab959d278d1075"
},
"http_status_code": 400,
"request_id": "d6ee553b-0e0f-4b68-81ff-e1c434fde032",
"retry_attempts": 0
}
}

MSG:

Couldn't create cluster my-cluster: An error occurred (InvalidParameterException) when calling the CreateCluster operation: The client request token parameter must be between 33 and 126 characters.

PLAY RECAP ***************************************************************************************************************************************************************************************
localhost : ok=27 changed=12 unreachable=0 failed=1 skipped=7 rescued=0 ignored=0

```


### Code of Conduct

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


Discussion:
I can confirm this.   
In your scenario only 5 characters are missing: 

```yml
---
- hosts: localhost
  connection: local

  tasks:
    - name: Create EKS cluster
      community.aws.aws_eks_cluster:
        name: jdelaportek8112345
        version: 1.21
        role_arn: myEKSClusterRole
        wait: true
        region: eu-central-1
        subnets:
          - subnet-d8309db2
          - subnet-943ad4d8
        security_groups:
          - sg-f32f0196
      register: create_eks

```
This is the bug: https://github.com/ansible-collections/community.aws/blob/main/plugins/modules/aws_eks_cluster.py#L207

> clientRequestToken (string) --
> Unique, case-sensitive identifier you provide to ensure the idempotency of the request.
> This field is autopopulated if not provided.

This token must be between 33 and 126 characters ...  
We can remove it to see if our integration tests still pass


Resolving patch:
diff --git a/plugins/modules/aws_eks_cluster.py b/plugins/modules/aws_eks_cluster.py
--- a/plugins/modules/aws_eks_cluster.py
+++ b/plugins/modules/aws_eks_cluster.py
@@ -204,7 +204,7 @@ def ensure_present(client, module):
                       resourcesVpcConfig=dict(
                           subnetIds=subnets,
                           securityGroupIds=groups),
-                      clientRequestToken='ansible-create-%s' % name)
+                      )
         if module.params['version']:
             params['version'] = module.params['version']
         cluster = client.create_cluster(**params)['cluster']


Test patch:
diff --git a/tests/integration/targets/aws_eks_cluster/defaults/main.yml b/tests/integration/targets/aws_eks_cluster/defaults/main.yml
--- a/tests/integration/targets/aws_eks_cluster/defaults/main.yml
+++ b/tests/integration/targets/aws_eks_cluster/defaults/main.yml
@@ -1,4 +1,5 @@
 eks_cluster_name: "{{ resource_prefix }}"
+eks_cluster_short_name: "{{ lookup('password', '/dev/null chars=ascii_lowercase length=5') }}"
 eks_subnets:
   - zone: a
     cidr: 10.0.1.0/24
diff --git a/tests/integration/targets/aws_eks_cluster/tasks/full_test.yml b/tests/integration/targets/aws_eks_cluster/tasks/full_test.yml
--- a/tests/integration/targets/aws_eks_cluster/tasks/full_test.yml
+++ b/tests/integration/targets/aws_eks_cluster/tasks/full_test.yml
@@ -77,8 +77,8 @@
     - name: create EKS cluster
       aws_eks_cluster:
         name: "{{ eks_cluster_name }}"
-        security_groups: "{{ eks_security_groups | community.general.json_query('[].name') }}"
-        subnets: "{{ setup_subnets.results | community.general.json_query('[].subnet.id') }}"
+        security_groups: "{{ eks_security_groups | map(attribute='name') }}"
+        subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
         role_arn: "{{ iam_role.arn }}"
       register: eks_create
 
@@ -91,8 +91,8 @@
     - name: create EKS cluster with same details but wait for it to become active
       aws_eks_cluster:
         name: "{{ eks_cluster_name }}"
-        security_groups: "{{ eks_security_groups | community.general.json_query('[].name') }}"
-        subnets: "{{ setup_subnets.results | community.general.json_query('[].subnet.id') }}"
+        security_groups: "{{ eks_security_groups | map(attribute='name') }}"
+        subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
         role_arn: "{{ iam_role.arn }}"
         wait: yes
       register: eks_create
@@ -111,8 +111,8 @@
     - name: create EKS cluster with same details but using SG ids
       aws_eks_cluster:
         name: "{{ eks_cluster_name }}"
-        security_groups: "{{ setup_security_groups.results | community.general.json_query('[].group_id') }}"
-        subnets: "{{ setup_subnets.results | community.general.json_query('[].subnet.id') }}"
+        security_groups: "{{ setup_security_groups.results | map(attribute='group_id') }}"
+        subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
         role_arn: "{{ iam_role.arn }}"
       register: eks_create
 
@@ -137,8 +137,8 @@
     - name: create EKS cluster with same details but wait for it to become active
       aws_eks_cluster:
         name: "{{ eks_cluster_name }}"
-        security_groups: "{{ eks_security_groups | community.general.json_query('[].name') }}"
-        subnets: "{{ setup_subnets.results | community.general.json_query('[].subnet.id') }}"
+        security_groups: "{{ eks_security_groups | map(attribute='name') }}"
+        subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
         role_arn: "{{ iam_role.arn }}"
         wait: yes
       register: eks_create
@@ -160,6 +160,28 @@
         that:
           - eks_delete is changed
 
+    - name: create EKS cluster with short name
+      aws_eks_cluster:
+        name: "{{ eks_cluster_short_name }}"
+        security_groups: "{{ eks_security_groups | map(attribute='name') }}"
+        subnets: "{{ setup_subnets.results | map(attribute='subnet.id') }}"
+        role_arn: "{{ iam_role.arn }}"
+      register: eks_create
+
+    - name: check that EKS cluster was created with short name
+      assert:
+        that:
+          - eks_create is changed
+          - eks_create.name == eks_cluster_short_name
+          - eks_create is not failed
+
+    - name: remove EKS cluster with short name
+      aws_eks_cluster:
+        name: "{{ eks_cluster_short_name }}"
+        state: absent
+        wait: yes
+      register: eks_delete
+
   always:
     - name: Announce teardown start
       debug:
@@ -173,6 +195,14 @@
       register: eks_delete
       ignore_errors: yes
 
+    - name: remove EKS cluster
+      aws_eks_cluster:
+        name: "{{ eks_cluster_short_name }}"
+        state: absent
+        wait: yes
+      register: eks_delete
+      ignore_errors: yes
+
     - debug:
         msg: "{{ eks_security_groups|reverse|list }}"