Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SASL/SCRAM + add option for SASL IAM & add option to disable unauthenticated clients #1764

6 changes: 6 additions & 0 deletions changelogs/fragments/1761-msk_cluster-fix-authentication.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
bugfixes:
- msk_cluster - fix creating a cluster with sasl_scram authentication (https://github.com/ansible-collections/community.aws/issues/1761).
minor_changes:
- msk_cluster - add option for sasl_iam authentication and add support to disable "unauthenticated" clients (https://github.com/ansible-collections/community.aws/issues/1761)
trivial:
- msk_cluster - changed test to 2.8.1 the recommended default version from MSK
32 changes: 25 additions & 7 deletions plugins/modules/msk_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,15 @@
sasl_scram:
description: SASL/SCRAM authentication is enabled or not.
type: bool
default: False
sasl_iam:
version_added: 5.5.0
description: IAM authentication is enabled or not.
type: bool
unauthenticated:
version_added: 5.5.0
description: Option to explicitly turn on or off authentication
type: bool
default: True
enhanced_monitoring:
description: Specifies the level of monitoring for the MSK cluster.
choices:
Expand Down Expand Up @@ -382,13 +390,21 @@ def prepare_create_options(module):

if module.params["authentication"]:
c_params["ClientAuthentication"] = {}
if module.params["authentication"].get("sasl_scram"):
c_params["ClientAuthentication"]["Sasl"] = {
"Scram": module.params["authentication"]["sasl_scram"]
}
if module.params["authentication"].get("sasl_scram") or module.params["authentication"].get("sasl_iam"):
sasl = {}
if module.params["authentication"].get("sasl_scram"):
sasl["Scram"] = {"Enabled": True}
if module.params["authentication"].get("sasl_iam"):
sasl["Iam"] = {"Enabled": True}
c_params["ClientAuthentication"]["Sasl"] = sasl
if module.params["authentication"].get("tls_ca_arn"):
c_params["ClientAuthentication"]["Tls"] = {
"CertificateAuthorityArnList": module.params["authentication"]["tls_ca_arn"]
"CertificateAuthorityArnList": module.params["authentication"]["tls_ca_arn"],
"Enabled": True,
}
if module.params["authentication"].get("unauthenticated"):
c_params["ClientAuthentication"] = {
"Unauthenticated": {"Enabled": True},
}

c_params.update(prepare_enhanced_monitoring_options(module))
Expand Down Expand Up @@ -713,7 +729,9 @@ def main():
type="dict",
options=dict(
tls_ca_arn=dict(type="list", elements="str", required=False),
sasl_scram=dict(type="bool", default=False),
sasl_scram=dict(type="bool", required=False),
sasl_iam=dict(type="bool", required=False),
unauthenticated=dict(type="bool", default=True, required=False),
),
),
enhanced_monitoring=dict(
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/targets/msk_cluster-auth/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cloud/aws
time=46m

msk_cluster
19 changes: 19 additions & 0 deletions tests/integration/targets/msk_cluster-auth/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
vpc_name: "{{ resource_prefix }}-mskc-a"
vpc_cidr: '10.{{ 256 | random(seed=resource_prefix) }}.0.0/16'
vpc_subnets:
- '10.{{ 256 | random(seed=resource_prefix) }}.100.0/24'
- '10.{{ 256 | random(seed=resource_prefix) }}.101.0/24'
vpc_subnet_name_prefix: "{{ resource_prefix }}"

msk_config_name: "{{ resource_prefix }}-msk-cluster-auth"
msk_cluster_name: "{{ tiny_prefix }}-msk-cluster-auth"
msk_version: 2.8.1
msk_broker_nodes: 2

tags_create:
key1: "value1"
key2: "value2"
tags_update:
key2: "value2"
key3: "value3"
1 change: 1 addition & 0 deletions tests/integration/targets/msk_cluster-auth/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dependencies: []
91 changes: 91 additions & 0 deletions tests/integration/targets/msk_cluster-auth/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
- name: aws_msk_cluster integration tests
module_defaults:
group/aws:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
security_token: "{{ security_token | default(omit) }}"
region: "{{ aws_region }}"
collections:
- amazon.aws
block:
- name: collect availability zone info
aws_az_info:
register: az_info

- name: assert there are at least two zones
assert:
that: az_info.availability_zones | length >= 2

- name: create vpc
ec2_vpc_net:
state: present
cidr_block: '{{ vpc_cidr }}'
name: '{{ vpc_name }}'
register: vpc

- name: create subnets
ec2_vpc_subnet:
state: present
cidr: '{{ item }}'
az: '{{ az_info.availability_zones[index].zone_name }}'
vpc_id: '{{ vpc.vpc.id }}'
tags:
Name: '{{ vpc_subnet_name_prefix }}-subnet-{{ index }}'
loop: "{{ vpc_subnets }}"
loop_control:
index_var: index
register: subnets

- set_fact:
subnet_ids: '{{ subnets | community.general.json_query("results[].subnet.id") | list }}'

# ============================================================
- name: create msk configuration
aws_msk_config:
name: "{{ msk_config_name }}"
state: "present"
kafka_versions:
- "{{ msk_version }}"
register: msk_config

- name: create test with sasl_iam
include_tasks: test_create_auth.yml

always:

- name: delete msk cluster
aws_msk_cluster:
name: "{{ msk_cluster_name }}"
state: absent
wait: true
ignore_errors: yes

- name: remove msk configuration
aws_msk_config:
name: "{{ msk_config_name }}"
state: absent
ignore_errors: yes

- name: remove subnets
ec2_vpc_subnet:
state: absent
cidr: '{{ item }}'
vpc_id: '{{ vpc.vpc.id }}'
loop: "{{ vpc_subnets }}"
ignore_errors: yes
register: removed_subnets
until: removed_subnets is succeeded
retries: 5
delay: 5

- name: remove the vpc
ec2_vpc_net:
state: absent
cidr_block: '{{ vpc_cidr }}'
name: '{{ vpc_name }}'
ignore_errors: yes
register: removed_vpc
until: removed_vpc is success
retries: 5
delay: 5
101 changes: 101 additions & 0 deletions tests/integration/targets/msk_cluster-auth/tasks/test_create_auth.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
- name: create a msk cluster with authentication flipped from default (check mode)
aws_msk_cluster:
name: "{{ msk_cluster_name }}"
state: "present"
version: "{{ msk_version }}"
nodes: "{{ msk_broker_nodes }}"
ebs_volume_size: 10
authentication:
sasl_iam: true
sasl_scram: true
unauthenticated: false
subnets: "{{ subnet_ids }}"
wait: true
tags: "{{ tags_create }}"
configuration_arn: "{{ msk_config.arn }}"
configuration_revision: "{{ msk_config.revision }}"
check_mode: yes
register: msk_cluster

- name: assert that the msk cluster be created
assert:
that:
- msk_cluster is changed

- name: create a msk cluster with authentication flipped from default
aws_msk_cluster:
name: "{{ msk_cluster_name }}"
state: "present"
version: "{{ msk_version }}"
nodes: "{{ msk_broker_nodes }}"
ebs_volume_size: 10
authentication:
sasl_iam: true
sasl_scram: true
unauthenticated: false
subnets: "{{ subnet_ids }}"
wait: true
tags: "{{ tags_create }}"
configuration_arn: "{{ msk_config.arn }}"
configuration_revision: "{{ msk_config.revision }}"
register: msk_cluster

- name: assert that the msk cluster is created
assert:
that:
- msk_cluster is changed

- name: validate return values
assert:
that:
- "'cluster_info' in msk_cluster"
- "'bootstrap_broker_string' in msk_cluster"
- "'key1' in msk_cluster.cluster_info.tags"
- "msk_cluster.cluster_info.tags.key1 == 'value1'"
- "msk_cluster.cluster_info.cluster_name == msk_cluster_name"
- "msk_cluster.cluster_info.number_of_broker_nodes == msk_broker_nodes"
- "msk_cluster.cluster_info.broker_node_group_info.instance_type == 'kafka.t3.small'"
- "msk_cluster.cluster_info.broker_node_group_info.storage_info.ebs_storage_info.volume_size == 10"
- "msk_cluster.cluster_info.client_authentication.sasl.iam.enabled == true"
- "msk_cluster.cluster_info.client_authentication.sasl.scram.enabled == true"
# Not always returned by API
# - "msk_cluster.cluster_info.client_authentication.unauthenticated.enabled == false"
- "msk_cluster.cluster_info.open_monitoring.prometheus.jmx_exporter.enabled_in_broker == false"
- "msk_cluster.cluster_info.cluster_arn.startswith('arn:aws:kafka:{{ aws_region }}:')"

- name: create a msk cluster with authentication flipped from default (idempotency)
aws_msk_cluster:
name: "{{ msk_cluster_name }}"
state: "present"
version: "{{ msk_version }}"
nodes: "{{ msk_broker_nodes }}"
ebs_volume_size: 10
authentication:
sasl_iam: true
sasl_scram: true
unauthenticated: false
subnets: "{{ subnet_ids }}"
wait: true
tags: "{{ tags_create }}"
configuration_arn: "{{ msk_config.arn }}"
configuration_revision: "{{ msk_config.revision }}"
register: msk_cluster

- name: assert that the msk cluster wasn't changed
assert:
that:
- msk_cluster is not changed

### Keep delete simple as we're not checking delete here
- name: delete msk cluster
aws_msk_cluster:
name: "{{ msk_cluster_name }}"
state: "absent"
wait: true
register: msk_cluster

- name: assert that the msk cluster is changed
assert:
that:
- msk_cluster is changed
2 changes: 1 addition & 1 deletion tests/integration/targets/msk_cluster/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ vpc_subnet_name_prefix: "{{ resource_prefix }}"

msk_config_name: "{{ resource_prefix }}-msk-cluster"
msk_cluster_name: "{{ tiny_prefix }}-msk-cluster"
msk_version: 2.6.0
msk_version: 2.8.1
msk_broker_nodes: 2

tags_create:
Expand Down