feat(garage): add provisioning of and bootstraping
This commit is contained in:
parent
188a6f539f
commit
19986e1205
4 changed files with 194 additions and 5 deletions
|
|
@ -36,11 +36,25 @@ garage_replication_factor: 1
|
||||||
garage_compression_level: 1
|
garage_compression_level: 1
|
||||||
garage_db_engine: "lmdb"
|
garage_db_engine: "lmdb"
|
||||||
garage_s3_region: "us-east-1"
|
garage_s3_region: "us-east-1"
|
||||||
garage_rpc_secret: "changeme_rpc_secret"
|
garage_rpc_secret: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
garage_admin_token: "changeme_admin_token"
|
garage_admin_token: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
garage_metrics_token: "changeme_metrics_token"
|
garage_metrics_token: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
|
|
||||||
# Traefik configuration
|
# Traefik configuration
|
||||||
garage_traefik_network: "proxy"
|
garage_traefik_network: "proxy"
|
||||||
garage_internal_network: "internal"
|
garage_internal_network: "internal"
|
||||||
garage_use_ssl: true
|
garage_use_ssl: true
|
||||||
|
|
||||||
|
# Optional: Garage cluster bootstrap configuration
|
||||||
|
garage_bootstrap_enabled: false
|
||||||
|
garage_bootstrap_zone: "dc1"
|
||||||
|
garage_bootstrap_capacity: "1G"
|
||||||
|
|
||||||
|
# Optional: S3 keys to create
|
||||||
|
# Example:
|
||||||
|
# garage_s3_keys:
|
||||||
|
# - name: "my-key"
|
||||||
|
# buckets:
|
||||||
|
# - name: "my-bucket"
|
||||||
|
# permissions: ["read", "write"]
|
||||||
|
garage_s3_keys: []
|
||||||
51
roles/garage/tasks/bootstrap.yml
Normal file
51
roles/garage/tasks/bootstrap.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# Provisioning tasks for garage (cluster bootstrap, S3 keys, and buckets)
|
||||||
|
# Cluster bootstrap tasks
|
||||||
|
- name: Get garage node ID
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage node id -q
|
||||||
|
register: _garage_node_id
|
||||||
|
|
||||||
|
- name: Extract short node ID
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_garage_node_id_short: "{{ _garage_node_id.stdout.split('@')[0] }}"
|
||||||
|
|
||||||
|
- name: Check if node layout is configured
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage layout show
|
||||||
|
register: _garage_layout_show
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Check if node is in layout
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_node_in_layout: "{{ _garage_node_id_short in _garage_layout_show.stdout }}"
|
||||||
|
|
||||||
|
- name: Configure garage node layout
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage layout assign -z {{ garage_bootstrap_zone }} -c {{ garage_bootstrap_capacity }} {{ _garage_node_id_short }}
|
||||||
|
register: _layout_assign_result
|
||||||
|
when:
|
||||||
|
- not _node_in_layout
|
||||||
|
|
||||||
|
- name: Extract current layout version
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_current_layout_version: "{{ _garage_layout_show.stdout | regex_search('Current cluster layout version: (\\d+)', '\\1') | first | default('0') }}"
|
||||||
|
when:
|
||||||
|
- _layout_assign_result is changed
|
||||||
|
|
||||||
|
- name: Calculate next layout version
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_next_layout_version: "{{ (_current_layout_version | int) + 1 }}"
|
||||||
|
when:
|
||||||
|
- _layout_assign_result is changed
|
||||||
|
|
||||||
|
- name: Apply garage layout
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage layout apply --version {{ _next_layout_version }}
|
||||||
|
when:
|
||||||
|
- _layout_assign_result is changed
|
||||||
|
|
@ -42,4 +42,33 @@
|
||||||
- name: Start garage container
|
- name: Start garage container
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ garage_docker_compose_dir }}"
|
project_src: "{{ garage_docker_compose_dir }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Wait for garage container to be running
|
||||||
|
community.docker.docker_container_info:
|
||||||
|
name: "{{ garage_service_name }}"
|
||||||
|
register: _garage_container_info
|
||||||
|
until: _garage_container_info.container.State.Running | default(false)
|
||||||
|
retries: 30
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Wait for garage to be ready (check if garage command responds)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage status
|
||||||
|
register: _garage_status_check
|
||||||
|
until: _garage_status_check.rc == 0
|
||||||
|
retries: 30
|
||||||
|
delay: 2
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
# Include bootstraping tasks (cluster bootstrap)
|
||||||
|
- name: Include garage bootstraping tasks
|
||||||
|
ansible.builtin.include_tasks: bootstrap.yml
|
||||||
|
when: garage_bootstrap_enabled
|
||||||
|
|
||||||
|
# Include provisioning tasks (S3 keys and buckets)
|
||||||
|
- name: Include garage bootstraping tasks
|
||||||
|
ansible.builtin.include_tasks: provision.yml
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
95
roles/garage/tasks/provision.yml
Normal file
95
roles/garage/tasks/provision.yml
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
# S3 keys and buckets tasks
|
||||||
|
- name: Get list of existing S3 keys
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage key list
|
||||||
|
register: _existing_keys_output
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Parse existing key names
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_existing_keys: "{{ _existing_keys_output.stdout_lines[1:] | select('match', '^GK') | map('regex_replace', '^\\S+\\s+\\S+\\s+(\\S+)\\s+.*$', '\\1') | list }}"
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Create S3 keys
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage key create {{ item.name }}
|
||||||
|
loop: "{{ garage_s3_keys }}"
|
||||||
|
register: _key_create_result
|
||||||
|
when:
|
||||||
|
- garage_s3_keys | length > 0
|
||||||
|
- item.name not in _existing_keys
|
||||||
|
|
||||||
|
- name: Get key IDs for all keys
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage key info {{ item.name }}
|
||||||
|
loop: "{{ garage_s3_keys }}"
|
||||||
|
register: _key_info_results
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Extract key IDs from info
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_key_id_map: "{{ _key_id_map | default({}) | combine({item.item.name: item.stdout | regex_search('Key ID:\\s+(\\S+)', '\\1') | first}) }}"
|
||||||
|
loop: "{{ _key_info_results.results }}"
|
||||||
|
when:
|
||||||
|
- garage_s3_keys | length > 0
|
||||||
|
- item.stdout is defined
|
||||||
|
|
||||||
|
- name: Get list of existing buckets
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage bucket list
|
||||||
|
register: _existing_buckets_output
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Parse existing bucket names
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_existing_buckets: "{{ _existing_buckets_output.stdout_lines[2:] | map('split') | map('first') | list }}"
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Get unique bucket names
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_unique_buckets: "{{ garage_s3_keys | subelements('buckets', skip_missing=True) | map(attribute='1.name') | unique | list }}"
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Create buckets
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage bucket create {{ item }}
|
||||||
|
loop: "{{ _unique_buckets }}"
|
||||||
|
when:
|
||||||
|
- garage_s3_keys | length > 0
|
||||||
|
- item not in _existing_buckets
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Set bucket permissions using key IDs
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage bucket allow {{ item.1.name }} {% for perm in item.1.permissions %}--{{ perm }} {% endfor %}--key {{ _key_id_map[item.0.name] }}
|
||||||
|
loop: "{{ garage_s3_keys | subelements('buckets', skip_missing=True) }}"
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
# Export key credentials for use by other roles
|
||||||
|
- name: Get detailed key information for all keys
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ garage_service_name }}"
|
||||||
|
command: /garage key info {{ item.name }}
|
||||||
|
loop: "{{ garage_s3_keys }}"
|
||||||
|
register: _key_details_results
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
|
|
||||||
|
- name: Build garage S3 credentials map
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
garage_s3_credentials: "{{ garage_s3_credentials | default({}) | combine({item.item.name: {'key_id': item.stdout | regex_search('Key ID:\\s+(\\S+)', '\\1') | first, 'secret_key': item.stdout | regex_search('Secret key:\\s+(\\S+)', '\\1') | first}}) }}"
|
||||||
|
loop: "{{ _key_details_results.results }}"
|
||||||
|
when:
|
||||||
|
- garage_s3_keys | length > 0
|
||||||
|
- item.stdout is defined
|
||||||
|
|
||||||
|
- name: Export garage S3 credentials as cacheable fact
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
garage_s3_credentials: "{{ garage_s3_credentials }}"
|
||||||
|
cacheable: true
|
||||||
|
when: garage_s3_keys | length > 0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue