Skip to content

Add support for DNS and only create instances that do not exist #9

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

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions apps/manual-kafka-cluster/collections.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ collections:
- name: community.crypto
version: 2.15.1
- name: linode.cloud
version: 0.16.1
version: 0.37.1
- name: community.general
version: 8.6.0
version: 8.6.0
7 changes: 6 additions & 1 deletion apps/manual-kafka-cluster/group_vars/kafka/vars
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ region: us-southeast
image: linode/ubuntu24.04
group:
linode_tags:
firewall_label:

# Optional settings for DNS
domain_name:
ttl_sec:

cluster_size: 3
client_count: 2
Expand All @@ -26,4 +31,4 @@ state_or_province_name: Pennsylvania
locality_name: Philadelphia
organization_name: Akamai Technologies
email_address: [email protected]
ca_common_name: Kafka RootCA
ca_common_name: Kafka RootCA
72 changes: 68 additions & 4 deletions apps/manual-kafka-cluster/provision.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,30 @@

tasks:

- name: get firewall info
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/firewall_info/
linode.cloud.firewall_info:
label: '{{ firewall_label }}'
api_token: '{{ api_token }}'
register: firewall_info
when: firewall_label|d(False)

- name: check if instances already created
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/instance_list/
linode.cloud.instance_list:
api_token: '{{ api_token }}'
filters:
- name: label
values: "{{ [ instance_prefix ] | product(range(1, cluster_size+1)) | map('join') | list }}"
order_by: label
register: existing_instances

- name: convert instances to a dict
set_fact:
existing_instances: "{{ dict(existing_instances.instances | map(attribute='label') | zip(existing_instances.instances)) }}"

- name: creating kafka servers
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/instance/
linode.cloud.instance:
label: '{{ instance_prefix }}{{ item }}'
api_token: '{{ api_token }}'
Expand All @@ -21,7 +44,9 @@
ua_prefix: 'docs-kafka-occ'
tags: '{{ linode_tags }}'
state: present
firewall_id: '{{ (firewall_info.firewall|default({})).id|default(omit) }}'
with_sequence: count='{{ cluster_size }}'
when: (instance_prefix + item) not in existing_instances

- name: get info about the instances
linode.cloud.instance_info:
Expand All @@ -30,6 +55,45 @@
register: info
with_sequence: count='{{ cluster_size }}'

- name: check if hosts are in DNS
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/domain_info/
linode.cloud.domain_info:
api_token: '{{ api_token }}'
domain: '{{ domain_name }}'
when: domain_name|d(False)
register: domain_info

- name: remove old hosts from dns
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/domain_record/
linode.cloud.domain_record:
api_token: '{{ api_token }}'
domain_id: '{{ domain_info.domain.id }}'
record_id: '{{ item.id }}'
state: absent
vars:
instance_ips: "{{ dict(info.results | map(attribute='instance.label') | zip(info.results | map(attribute='networking.ipv4.public.0.address'))) }}"
when:
- domain_name|d(False)
- domain_info|d(False)
- item.name in instance_ips
- item.target != instance_ips[item.name]
with_items: "{{ domain_info.records }}"

- name: add new hosts to dns
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/domain_record/
linode.cloud.domain_record:
api_token: '{{ api_token }}'
domain_id: '{{ domain_info.domain.id }}'
name: '{{ item.instance.label }}'
target: '{{ item.instance.ipv4[0] }}'
ttl_sec: '{{ ttl_sec | default(omit) }}'
type: 'A'
state: present
with_items: "{{ info.results }}"
when:
- domain_name|d(False)
- domain_info|d(False)

- name: update group_vars
blockinfile:
path: ./group_vars/kafka/vars
Expand All @@ -39,9 +103,9 @@
kafka_data:
server:
{%- for count in range(cluster_size) %}
- kafka{{ count + 1 }}:
- name: {{ info.results[count].instance.label }}
instance:
hostname: kafka{{ count + 1 }}
hostname: {{ info.results[count].instance.label }}{% if domain_name|d(False) and domain_info %}.{{ domain_name }}{% endif %}
ip_pub1: {{ info.results[count].instance.ipv4[0] }}
ip_priv1: {{ info.results[count].instance.ipv4[1] }}
{%- endfor %}
Expand All @@ -54,13 +118,13 @@
#jinja2: trim_blocks:False
[kafka]
{%- for count in range(cluster_size) %}
{{ info.results[count].instance.ipv4[0] }} {% if count < controller_count %}role='controller and broker'{%else%}role='broker only'{%endif%}
{{ info.results[count].networking.ipv4.public[0].rdns }} {% if count < controller_count %}role='controller and broker'{%else%}role='broker only'{%endif%}
{%- endfor %}

- name: wait for port 22 to become open
wait_for:
port: 22
host: '{{ item.instance.ipv4[0] }}'
host: '{{ item.networking.ipv4.public[0].rdns }}'
search_regex: OpenSSH
delay: 10
connection: local
Expand Down
2 changes: 1 addition & 1 deletion apps/manual-kafka-cluster/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ pyyaml==6.0.1
dnspython==2.2.1
passlib==1.7.4
## cloud.linode module dependancies ##
linode-api4==5.15.1
linode-api4==5.29.0
polling==0.3.2
ansible-specdoc==0.0.14
3 changes: 3 additions & 0 deletions apps/manual-kafka-cluster/roles/common/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@

- name: apply ufw rules
import_tasks: ufw_rules.yml

- name: reboot linode
reboot:
21 changes: 18 additions & 3 deletions apps/manual-kafka-cluster/roles/kafka/tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,31 @@
index_var: count
when: hostvars[groups['kafka'][count]].role == 'broker only'

- name: check existing kafka cluster uuid
shell:
cmd: grep -s cluster.id {{ kafka_data_directory }}/data/kraft-combined-logs/meta.properties | cut -f 2 -d = || /bin/true
removes: "{{ kafka_data_directory}}/data/kraft-combined-logs/meta.properties"
register: old_cluster_uuid
run_once: true
delegate_to: "{{ groups['kafka'][0] }}"

- name: create kafka cluster uuid
command:
cmd: "{{ kafka_bin_directory }}/kafka-storage.sh random-uuid"
register: cluster_uuid
creates: "{{ kafka_data_directory}}/data/kraft-combined-logs/meta.properties"
register: new_cluster_uuid
run_once: true
delegate_to: "{{ groups['kafka'][0] }}"

- name: determine kafka cluster uuid
set_fact:
cluster_uuid: "{{ (old_cluster_uuid.changed) | ternary(old_cluster_uuid.stdout, new_cluster_uuid.stdout) }}"
run_once: true
delegate_to: "{{ groups['kafka'][0] }}"

- name: format data directory for controller and broker nodes
command:
cmd: "{{ kafka_bin_directory }}/kafka-storage.sh format -t {{ cluster_uuid.stdout }} -c {{ kafka_config_directory }}/config/kraft/server.properties"
cmd: "{{ kafka_bin_directory }}/kafka-storage.sh format -t {{ cluster_uuid}} -c {{ kafka_config_directory }}/config/kraft/server.properties --ignore-formatted"
become: true
become_user: kafka
run_once: true
Expand All @@ -72,7 +87,7 @@

- name: format data directory broker nodes
command:
cmd: "{{ kafka_bin_directory }}/kafka-storage.sh format -t {{ cluster_uuid.stdout }} -c {{ kafka_config_directory }}/config/kraft/broker.properties"
cmd: "{{ kafka_bin_directory }}/kafka-storage.sh format -t {{ cluster_uuid}} -c {{ kafka_config_directory }}/config/kraft/broker.properties --ignore-formatted"
become: true
become_user: kafka
run_once: true
Expand Down
4 changes: 2 additions & 2 deletions apps/manual-kafka-cluster/roles/kafka/tasks/hostname.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
block: |
#jinja2: trim_blocks:False
{%- for count in range(cluster_size) %}
{{ kafka_data.server[count].instance.ip_priv1 }} {{ kafka_data.server[count].instance.hostname }}
{{ kafka_data.server[count].instance.ip_priv1 }} {{ kafka_data.server[count].instance.hostname }} {{ kafka_data.server[count].name }}
{%- endfor %}

- name: configure hostnames
Expand All @@ -19,4 +19,4 @@
delegate_to: "{{ item }}"
loop: "{{ groups['kafka'] }}"
loop_control:
index_var: count
index_var: count
66 changes: 66 additions & 0 deletions apps/manual-kafka-cluster/shutdown.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
# shutdown kafka server and client instances
- name: shutdown kafka instances
hosts: localhost
vars_files:
- group_vars/kafka/vars
- group_vars/kafka/secret_vars

tasks:

# DNS

- name: check if hosts are in DNS
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/domain_info/
linode.cloud.domain_info:
api_token: '{{ api_token }}'
domain: '{{ domain_name }}'
when: domain_name|d(False)
register: domain_info

- name: remove hosts from dns
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/domain_record/
linode.cloud.domain_record:
api_token: '{{ api_token }}'
domain_id: '{{ domain_info.domain.id }}'
record_id: '{{ item.id }}'
state: absent
when:
- domain_name|d(False)
- domain_info|d(False)
- item.target in (kafka_data.server | map(attribute='instance.ip_pub1'))
with_items: "{{ domain_info.records }}"


# Instances

- name: get list of instances
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/instance_list/
linode.cloud.instance_list:
api_token: '{{ api_token }}'
filters:
- name: label
values: "{{ [ instance_prefix ] | product(range(1, cluster_size+1)) | map('join') | list }}"
order_by: label
register: existing_instances

- name: shutdown kafka servers
# https://galaxy.ansible.com/ui/repo/published/linode/cloud/content/module/instance/
linode.cloud.instance:
label: '{{ item.label }}'
api_token: '{{ api_token }}'
region: '{{ region }}'
state: absent
with_items: '{{ existing_instances.instances }}'

- name: update group_vars
blockinfile:
path: ./group_vars/kafka/vars
marker: "# {mark} INSTANCE VARS"
state: absent

- name: remove kafka nodes from inventory
blockinfile:
path: ./hosts
marker: "# {mark} KAFKA INSTANCES"
state: absent