bootstrap-bk-set.yaml
Overview
This Ansible playbook automates the process of bootstrapping a BK set in a distributed system. It queries the current BK set sequence number to determine if bootstrapping is necessary, manages the registration of the node's public wallet key, waits for the BK set to be properly updated with the node's information, and prepares the node environment by installing the BK set configuration and starting the necessary services via Docker Compose.
The main purpose of this playbook is to ensure that a node joins the BK set correctly during initial setup or system recovery, handling synchronization and configuration tasks automatically.
Task Breakdown and Functional Details
1. Query BK set sequence number
- name: Query BK set sequence number
uri:
url: "http://{{ HOST_PUBLIC_IP }}:{{ BIND_API_PORT }}/v2/bk_set"
return_content: yes
register: api_response
until: api_response.status == 200
retries: 30
delay: 3
Purpose: Sends HTTP GET requests to the BK set API endpoint to retrieve the current sequence number (
seq_no), which indicates the BK set version.Parameters:
url: Constructed dynamically from host IP and API port variables.return_content: Ensures the response content is returned for further processing.until: Retries until a successful HTTP 200 status is received.retriesanddelay: Limits retry attempts and wait time between retries.
Usage: This step is critical to determine if the node needs to perform bootstrap actions based on the BK set version.
2. Set bootstrap flag based on sequence number
- name: Set bootstrap flag based on sequence number
set_fact:
WANT_BOOTSTRAP: "{{ api_response.json.seq_no == 0 }}"
Purpose: Sets a boolean fact
WANT_BOOTSTRAPtotrueif the BK set sequence number is zero, indicating the BK set is uninitialized.Parameters: Uses
api_response.json.seq_nofrom the previous task.Usage: Controls the decision to proceed with bootstrapping.
3. Exit if bootstrap is not needed
- name: Exit if bootstrap is not needed
meta: end_host
when: not WANT_BOOTSTRAP
Purpose: Terminates the playbook execution for the current host if bootstrapping is unnecessary.
Usage: Prevents redundant operations when the BK set is already initialized.
4. Get public wallet key
- name: Get public wallet key
ansible.builtin.shell:
chdir: "{{ BK_DIR }}/bk-configs/"
cmd: "cat {{ NODE_OWNER_KEY | basename }} | jq -r '.public'"
register: BK_PUBLIC_KEY_OUTPUT
Purpose: Extracts the public wallet key of the node owner by reading a JSON key file and parsing it with
jq.Parameters:
chdir: Changes directory to where BK configuration files are stored.cmd: Reads the public key field from the owner's key JSON file.
Return: Captures the public key string in
BK_PUBLIC_KEY_OUTPUT.stdout.
5. Register public wallet key
- name: Register public wallet key
ansible.builtin.set_fact:
BK_OWNER_WALLET_PUBKEY: "{{ BK_PUBLIC_KEY_OUTPUT.stdout }}"
Purpose: Stores the extracted public wallet key in a fact variable for later reference.
6. Wait 5 seconds before checking BK set
- name: Wait 5 seconds before checking BK set
pause:
seconds: 5
Purpose: Introduces a short delay to allow system state propagation before querying the BK set again.
7. Wait for our public key to appear in BK set update
- name: Wait for our public key to appear in BK set update
uri:
url: "{{ BOOTSTRAP_BK_SET_URL }}"
method: GET
return_content: true
status_code: 200
register: resp
until: resp is succeeded and (BK_OWNER_WALLET_PUBKEY in resp.content)
retries: 60
delay: 5
Purpose: Polls the BK set update endpoint until the node's public wallet key appears in the BK set data.
Parameters:
url: URL for the BK set bootstrap endpoint.until: Waits until successful response and presence of the public key in the response content.retriesanddelay: Controls polling frequency and maximum retries.
Usage: Ensures the node is recognized in the BK set before proceeding.
8. Install collected BK set
- name: Install collected BK set
copy:
content: "{{ resp.content }}"
dest: "{{ BK_DIR }}/bk-configs/bk_set.json"
Purpose: Saves the BK set JSON data fetched from the bootstrap URL into the node's configuration directory.
Usage: Prepares the node with the latest BK set configuration.
9. Set HAS_BK_SET_FILE fact
- name: Set HAS_BK_SET_FILE fact
ansible.builtin.set_fact:
HAS_BK_SET_FILE: true
Purpose: Sets a flag indicating that the BK set file is present on the node.
10. Node graceful shutdown
- name: Node graceful shutdown
include_tasks: graceful-shutdown.yaml
Purpose: Includes an external task file to perform a graceful shutdown of the node services.
Usage: Ensures a clean restart environment before applying new configuration.
11. Production compose
- name: Production compose
ansible.builtin.template:
src: templates/docker-compose.j2
dest: "{{ BK_DIR }}/docker-compose.yaml"
mode: "0644"
Purpose: Renders a Docker Compose YAML file from a Jinja2 template, customizing it for the node environment.
Usage: Sets up the necessary container orchestration configuration.
12. Compose up
- name: Compose up
ansible.builtin.shell:
chdir: "{{ BK_DIR }}"
cmd: docker compose up -d --remove-orphans
Purpose: Runs Docker Compose to start the containers in detached mode and remove orphaned containers.
Usage: Launches the node services according to the generated Docker Compose configuration.
Implementation Details and Algorithms
Polling with Retry Logic: The playbook uses Ansible's
until,retries, anddelayfeatures extensively to implement retry logic for HTTP requests. This ensures robustness when waiting for external system readiness or updates.Condition-based Execution: Using
set_factand conditionalwhenclauses, it dynamically controls the flow, particularly deciding whether bootstrapping is necessary.Public Key Verification: The node waits until its public wallet key is visible in the BK set, which acts as a synchronization point confirming successful registration in the distributed set.
Graceful Shutdown Integration: Incorporating an external task file for graceful shutdown ensures that node restarts do not cause abrupt service interruptions.
Template-driven Configuration: The Docker Compose setup allows for flexible and reproducible service deployment tailored by environment variables and template parameters.
Interaction with Other System Components
BK Set API: Interacts with a RESTful API endpoint (
/v2/bk_set) to query and monitor the BK set state.Wallet Key Files: Reads wallet key files located in the BK configuration directory to obtain the node's cryptographic identity.
Bootstrap BK Set URL: Queries a specific bootstrap URL to retrieve updated BK set information.
Graceful Shutdown Tasks: Includes the
graceful-shutdown.yamltask file, which manages service shutdown procedures.Docker Environment: Generates and runs Docker Compose configurations to manage containerized node services.
Visual Diagram: Task Workflow Flowchart
flowchart TD
A[Query BK set seq_no] --> B{seq_no == 0?}
B -- Yes --> C[Extract public wallet key]
C --> D[Register public wallet key fact]
D --> E[Pause 5 seconds]
E --> F[Wait for public key in BK set]
F --> G[Install BK set file]
G --> H[Set HAS_BK_SET_FILE fact]
H --> I[Node graceful shutdown]
I --> J[Render docker-compose.yaml]
J --> K[Run docker compose up]
B -- No --> L[End playbook for host]
The diagram depicts the decision-making and execution flow, starting from querying the BK set sequence number, conditionally bootstrapping, waiting for synchronization, and finally launching the node services.