Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@ ansible-playbook ansible/deploy-client.yml --private-key ~/.ssh/id_rsa

The playbooks can all be run in any order. However they are designed with the assumption that you will run only either the TLS or non TLS playbooks, not both. Currently we do not support converting a cluster from non-TLS to TLS or vice versa.

## SASL Authentication Deployments

### TLS + SASL Cluster

Deploy a cluster with both TLS encryption and SASL authentication:

```bash
export REDPANDA_SASL_PASSWORD="your-secure-password"
export SR_SERVICE_PASSWORD="schema-registry-password"
export PP_SERVICE_PASSWORD="pandaproxy-password"

ansible-playbook ansible/provision-cluster-tls-sasl.yml \
--private-key ~/.ssh/id_rsa \
--inventory artifacts/hosts_gcp_$DEPLOYMENT_PREFIX.ini
```

### Managing Users and ACLs

After deploying a SASL-enabled cluster, you can manage additional users and ACLs:

```bash
export REDPANDA_SASL_PASSWORD="your-admin-password"
export PRODUCER_APP_PASSWORD="producer-password"
export CONSUMER_APP_PASSWORD="consumer-password"

ansible-playbook ansible/manage-sasl-users.yml \
--private-key ~/.ssh/id_rsa \
--inventory artifacts/hosts_gcp_$DEPLOYMENT_PREFIX.ini
```

## Additional Documentation

More information on consuming this collection
Expand Down
76 changes: 76 additions & 0 deletions ansible/manage-sasl-users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
# manages users, roles, and ACLs declaratively via user_management role
- name: Manage SASL Users, Roles, and ACLs
hosts: redpanda[0]
become: true
vars:
enable_tls: true
redpanda_truststore_file: "/etc/redpanda/certs/truststore.pem"
sasl_admin_username: "admin"
sasl_admin_password: "{{ lookup('env', 'REDPANDA_SASL_PASSWORD') }}"

# users (set state: absent to delete)
sasl_users:
- username: "producer_app"
password: "{{ lookup('env', 'PRODUCER_APP_PASSWORD') | default('producer-secret', true) }}"
mechanism: "SCRAM-SHA-256"
state: present

- username: "consumer_app"
password: "{{ lookup('env', 'CONSUMER_APP_PASSWORD') | default('consumer-secret', true) }}"
mechanism: "SCRAM-SHA-256"
state: present

# roles (enterprise RBAC)
sasl_roles: []

# kafka ACLs
sasl_acls:
- principal: "User:producer_app"
resource_type: topic
resource_name: "events-"
pattern_type: prefixed
operation:
- write
- describe
permission: allow
state: present

- principal: "User:consumer_app"
resource_type: topic
resource_name: "events-"
pattern_type: prefixed
operation:
- read
- describe
permission: allow
state: present

- principal: "User:consumer_app"
resource_type: group
resource_name: "consumer-"
pattern_type: prefixed
operation: read
permission: allow
state: present

# schema registry ACLs (enterprise)
schema_registry_acls:
- principal: "User:producer_app"
resource_type: subject
resource_name: "events-"
pattern_type: prefixed
operation: write
permission: allow
state: present

- principal: "User:consumer_app"
resource_type: subject
resource_name: "events-"
pattern_type: prefixed
operation: read
permission: allow
state: present

roles:
- role: redpanda.cluster.user_management

Check failure on line 76 in ansible/manage-sasl-users.yml

View workflow job for this annotation

GitHub Actions / Ansible Lint

syntax-check[specific]

the role 'redpanda.cluster.user_management' was not found in /home/runner/work/deployment-automation/deployment-automation/ansible/roles:/home/runner/work/deployment-automation/deployment-automation/.ansible/roles:/home/runner/work/deployment-automation/deployment-automation/artifacts/roles:/home/runner/work/deployment-automation/deployment-automation/ansible
30 changes: 26 additions & 4 deletions ansible/operation-apply-license.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,54 @@
vars:
rpk_bin: rpk

# SASL/TLS settings for authenticated clusters
kafka_enable_authorization: false
admin_api_require_auth: false
sasl_superuser_username: "admin"
sasl_superuser_password: ""
enable_tls: false
redpanda_truststore_file: /etc/redpanda/certs/truststore.pem
redpanda_kafka_port: 9092

rpk_opts: >-
-X brokers={{ hostvars[inventory_hostname].private_ip | default(ansible_default_ipv4.address) }}:{{ redpanda_kafka_port }}
{% if enable_tls | default(false) %}-X tls.enabled=true -X tls.ca={{ redpanda_truststore_file }}{% endif %}
{% if kafka_enable_authorization | default(false) and sasl_superuser_password != '' %}-X user={{ sasl_superuser_username }} -X pass={{ sasl_superuser_password }} -X sasl.mechanism=SCRAM-SHA-256{% endif %}

rpk_admin_opts: >-
{% if enable_tls | default(false) %}-X admin.tls.enabled=true -X admin.tls.ca={{ redpanda_truststore_file }}{% endif %}
{% if admin_api_require_auth | default(false) and sasl_superuser_password != '' %}-X user={{ sasl_superuser_username }} -X pass={{ sasl_superuser_password }}{% endif %}

tasks:
- name: Check cluster health
ansible.builtin.shell: |
{{ rpk_bin }} cluster health | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
{{ rpk_bin }} cluster health {{ rpk_opts }} {{ rpk_admin_opts }} | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
register: health_check
run_once: true
failed_when: "health_check.stdout != 'true'"
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Set Redpanda license (string)
ansible.builtin.command: rpk cluster license set {{ redpanda_license }}
ansible.builtin.command: "{{ rpk_bin }} cluster license set {{ redpanda_license }} {{ rpk_opts }} {{ rpk_admin_opts }}"
run_once: true
changed_when: false
when:
- redpanda_license is defined
no_log: true

- name: Set Redpanda license (path)
ansible.builtin.command: rpk cluster license set --path {{ redpanda_license_path }}
ansible.builtin.command: "{{ rpk_bin }} cluster license set --path {{ redpanda_license_path }} {{ rpk_opts }} {{ rpk_admin_opts }}"
changed_when: false
run_once: true
when:
- redpanda_license_path is defined
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Check broker status
ansible.builtin.shell: |
{{ rpk_bin }} redpanda admin brokers list | grep -q 'active.*true'
{{ rpk_bin }} redpanda admin brokers list {{ rpk_admin_opts }} | grep -q 'active.*true'
register: broker_status
changed_when: false
failed_when: broker_status.rc != 0
no_log: "{{ kafka_enable_authorization | default(false) }}"
24 changes: 22 additions & 2 deletions ansible/operation-configure-logging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,34 @@
vars:
rpk_bin: rpk

# SASL/TLS settings for authenticated clusters
kafka_enable_authorization: false
admin_api_require_auth: false
sasl_superuser_username: "admin"
sasl_superuser_password: ""
enable_tls: false
redpanda_truststore_file: /etc/redpanda/certs/truststore.pem
redpanda_kafka_port: 9092

rpk_opts: >-
-X brokers={{ hostvars[inventory_hostname].private_ip | default(ansible_default_ipv4.address) }}:{{ redpanda_kafka_port }}
{% if enable_tls | default(false) %}-X tls.enabled=true -X tls.ca={{ redpanda_truststore_file }}{% endif %}
{% if kafka_enable_authorization | default(false) and sasl_superuser_password != '' %}-X user={{ sasl_superuser_username }} -X pass={{ sasl_superuser_password }} -X sasl.mechanism=SCRAM-SHA-256{% endif %}

rpk_admin_opts: >-
{% if enable_tls | default(false) %}-X admin.tls.enabled=true -X admin.tls.ca={{ redpanda_truststore_file }}{% endif %}
{% if admin_api_require_auth | default(false) and sasl_superuser_password != '' %}-X user={{ sasl_superuser_username }} -X pass={{ sasl_superuser_password }}{% endif %}

tasks:
- name: Check cluster health
ansible.builtin.shell: |
set -o pipefail
{{ rpk_bin }} cluster health | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
{{ rpk_bin }} cluster health {{ rpk_opts }} {{ rpk_admin_opts }} | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
register: health_check
run_once: true
failed_when: "health_check.stdout != 'true'"
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Apply logging role
ansible.builtin.include_role:
Expand Down Expand Up @@ -59,10 +78,11 @@
- name: Check broker status
ansible.builtin.shell: |
set -o pipefail
{{ rpk_bin }} redpanda admin brokers list | grep -q 'active.*true'
{{ rpk_bin }} redpanda admin brokers list {{ rpk_admin_opts }} | grep -q 'active.*true'
register: broker_status
changed_when: false
failed_when: broker_status.rc != 0
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Display logging configuration summary
ansible.builtin.debug:
Expand Down
45 changes: 36 additions & 9 deletions ansible/operation-rolling-restart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,66 @@
vars:
rpk_bin: rpk

# SASL/TLS settings for authenticated clusters
kafka_enable_authorization: false
admin_api_require_auth: false
sasl_superuser_username: "admin"
sasl_superuser_password: ""
enable_tls: false
redpanda_truststore_file: /etc/redpanda/certs/truststore.pem
redpanda_kafka_port: 9092

rpk_opts: >-
-X brokers={{ hostvars[inventory_hostname].private_ip | default(ansible_default_ipv4.address) }}:{{ redpanda_kafka_port }}
{% if enable_tls | default(false) %}-X tls.enabled=true -X tls.ca={{ redpanda_truststore_file }}{% endif %}
{% if kafka_enable_authorization | default(false) and sasl_superuser_password != '' %}-X user={{ sasl_superuser_username }} -X pass={{ sasl_superuser_password }} -X sasl.mechanism=SCRAM-SHA-256{% endif %}

rpk_admin_opts: >-
{% if enable_tls | default(false) %}-X admin.tls.enabled=true -X admin.tls.ca={{ redpanda_truststore_file }}{% endif %}
{% if admin_api_require_auth | default(false) and sasl_superuser_password != '' %}-X user={{ sasl_superuser_username }} -X pass={{ sasl_superuser_password }}{% endif %}

tasks:
- name: Check cluster health
ansible.builtin.shell: |
{{ rpk_bin }} cluster health | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
{{ rpk_bin }} cluster health {{ rpk_opts }} {{ rpk_admin_opts }} | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
register: health_check
failed_when: "health_check.stdout != 'true'"
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Get node ID
ansible.builtin.shell: |
{{ rpk_bin }} cluster info | awk '$2 == "{{ ansible_host }}" {gsub("\\*", "", $1); print $1}'
{{ rpk_bin }} cluster info {{ rpk_opts }} | awk '$2 == "{{ ansible_host }}" {gsub("\\*", "", $1); print $1}'
register: node_id
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Enable maintenance mode
ansible.builtin.command: "{{ rpk_bin }} cluster maintenance enable {{ node_id.stdout }} --wait"
ansible.builtin.command: "{{ rpk_bin }} cluster maintenance enable {{ node_id.stdout }} --wait {{ rpk_opts }} {{ rpk_admin_opts }}"
register: maintenance_result
failed_when:
- "'Successfully enabled maintenance mode' not in maintenance_result.stdout"
- "'Maintenance mode is already enabled for node' not in maintenance_result.stdout"
changed_when: "'Successfully enabled maintenance mode' in maintenance_result.stdout"
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Verify maintenance mode status
ansible.builtin.shell: |
{{ rpk_bin }} cluster maintenance status | grep -q '{{ node_id.stdout }}'
{{ rpk_bin }} cluster maintenance status {{ rpk_opts }} {{ rpk_admin_opts }} | grep -q '{{ node_id.stdout }}'
register: maintenance_status
failed_when: maintenance_status.rc != 0
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Check cluster health after enabling maintenance mode
ansible.builtin.shell: |
{{ rpk_bin }} cluster health --watch --exit-when-healthy | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
{{ rpk_bin }} cluster health --watch --exit-when-healthy {{ rpk_opts }} {{ rpk_admin_opts }} | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
register: health_check_maintenance
failed_when: "health_check_maintenance.stdout != 'true'"
retries: 10
delay: 30
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Stop Redpanda service
ansible.builtin.systemd:
Expand All @@ -55,30 +78,34 @@
state: started

- name: Disable maintenance mode
ansible.builtin.command: "{{ rpk_bin }} cluster maintenance disable {{ node_id.stdout }}"
ansible.builtin.command: "{{ rpk_bin }} cluster maintenance disable {{ node_id.stdout }} {{ rpk_opts }} {{ rpk_admin_opts }}"
register: disable_maintenance_result
changed_when: "'Successfully disabled maintenance mode' in disable_maintenance_result.stdout"
failed_when: "'Successfully disabled maintenance mode' not in disable_maintenance_result.stdout"
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Verify maintenance mode is disabled
ansible.builtin.shell: |
{{ rpk_bin }} cluster maintenance status | grep -qv '{{ node_id.stdout }}'
{{ rpk_bin }} cluster maintenance status {{ rpk_opts }} {{ rpk_admin_opts }} | grep -qv '{{ node_id.stdout }}'
register: maintenance_status_after
failed_when: maintenance_status_after.rc != 0
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Check cluster health after disabling maintenance mode
ansible.builtin.shell: |
{{ rpk_bin }} cluster health --watch --exit-when-healthy | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
{{ rpk_bin }} cluster health --watch --exit-when-healthy {{ rpk_opts }} {{ rpk_admin_opts }} | grep -i 'healthy:' | tr -d '[:space:]' | awk -F ':' '{print tolower($2)}'
register: health_check_maintenance
failed_when: "health_check_maintenance.stdout != 'true'"
retries: 10
delay: 30
changed_when: false
no_log: "{{ kafka_enable_authorization | default(false) }}"

- name: Check broker status
ansible.builtin.shell: |
{{ rpk_bin }} redpanda admin brokers list | grep -q 'active.*true'
{{ rpk_bin }} redpanda admin brokers list {{ rpk_admin_opts }} | grep -q 'active.*true'
register: broker_status
changed_when: false
failed_when: broker_status.rc != 0
no_log: "{{ kafka_enable_authorization | default(false) }}"
Loading
Loading