--- # Garage S3 Cluster Setup (3 nodes, replication factor 3) # # Usage: # # Full deployment: # ansible-playbook -i inventory.ini playbooks/garage.yml # # # Just install/configure (no layout): # ansible-playbook -i inventory.ini playbooks/garage.yml --tags install # # # Just configure layout (after install): # ansible-playbook -i inventory.ini playbooks/garage.yml --tags layout - name: Install and Configure Garage on All Nodes hosts: garage become: true tags: [install] vars_files: - ../vault/secrets.yml tasks: - name: Download Garage binary get_url: url: "https://garagehq.deuxfleurs.fr/_releases/v1.0.1/x86_64-unknown-linux-musl/garage" dest: /usr/local/bin/garage mode: '0755' - name: Create garage user user: name: garage system: true shell: /sbin/nologin home: /var/lib/garage create_home: false - name: Create garage directories file: path: "{{ item }}" state: directory owner: garage group: garage mode: '0750' loop: - /var/lib/garage - /var/lib/garage/meta - /var/lib/garage/data - /etc/garage - name: Deploy garage configuration template: src: ../templates/garage.toml.j2 dest: /etc/garage/garage.toml owner: garage group: garage mode: '0600' notify: restart garage - name: Deploy garage systemd service copy: dest: /etc/systemd/system/garage.service content: | [Unit] Description=Garage S3-compatible object storage Documentation=https://garagehq.deuxfleurs.fr/ After=network.target nebula.service Wants=network-online.target [Service] Type=simple User=garage Group=garage ExecStart=/usr/local/bin/garage -c /etc/garage/garage.toml server Restart=always RestartSec=5 [Install] WantedBy=multi-user.target mode: '0644' notify: - reload systemd - restart garage - name: Flush handlers to apply config before starting meta: flush_handlers - name: Start and enable garage systemd: name: garage state: started enabled: true daemon_reload: true - name: Wait for Garage RPC to be ready wait_for: host: "{{ nebula_ip }}" port: 3901 timeout: 30 - name: Get node ID command: garage -c /etc/garage/garage.toml node id -q register: node_id changed_when: false - name: Display node ID debug: msg: "Node {{ inventory_hostname }}: {{ node_id.stdout }}" handlers: - name: reload systemd systemd: daemon_reload: true - name: restart garage systemd: name: garage state: restarted - name: Configure Garage Cluster Layout hosts: garage-01 become: true tags: [layout] vars_files: - ../vault/secrets.yml tasks: - name: Wait for all nodes to connect pause: seconds: 10 - name: Check cluster status command: garage -c /etc/garage/garage.toml status register: cluster_status changed_when: false - name: Display cluster status debug: msg: "{{ cluster_status.stdout_lines }}" - name: Get current layout command: garage -c /etc/garage/garage.toml layout show register: layout_show changed_when: false - name: Check if layout needs configuration set_fact: layout_needs_config: "{{ 'no role' in layout_show.stdout }}" - name: Get node IDs for layout command: garage -c /etc/garage/garage.toml status register: status_output changed_when: false when: layout_needs_config - name: Parse node IDs set_fact: node_ids: "{{ status_output.stdout | regex_findall('([a-f0-9]{16})\\s+' + item + '\\s') }}" loop: - "{{ hostvars['garage-01']['nebula_ip'] }}" - "{{ hostvars['garage-02']['nebula_ip'] }}" - "{{ hostvars['garage-03']['nebula_ip'] }}" register: parsed_nodes when: layout_needs_config - name: Assign layout to nodes command: > garage -c /etc/garage/garage.toml layout assign -z dc1 -c 200GB -t {{ item.item | regex_replace('10\\.10\\.10\\.(\\d+)', 'garage-\\1') | regex_replace('garage-39', 'garage-01') | regex_replace('garage-40', 'garage-02') | regex_replace('garage-41', 'garage-03') }} {{ item.ansible_facts.node_ids[0] }} loop: "{{ parsed_nodes.results }}" when: layout_needs_config and item.ansible_facts.node_ids is defined and item.ansible_facts.node_ids | length > 0 - name: Apply layout command: garage -c /etc/garage/garage.toml layout apply --version 1 when: layout_needs_config register: layout_apply - name: Display layout result debug: var: layout_apply.stdout_lines when: layout_apply is changed - name: Show final layout command: garage -c /etc/garage/garage.toml layout show register: final_layout changed_when: false - name: Display final layout debug: msg: "{{ final_layout.stdout_lines }}"