307 lines
11 KiB
YAML
307 lines
11 KiB
YAML
---
|
|
- name: Require Flatcar Linux
|
|
ansible.builtin.assert:
|
|
that:
|
|
- flatcar_os_release.stdout is search('ID=flatcar')
|
|
fail_msg: This role is for Flatcar Linux. Use bootstrap-k3s.yml for K3s hosts.
|
|
|
|
- name: Read host architecture
|
|
ansible.builtin.raw: uname -m
|
|
register: host_architecture
|
|
changed_when: false
|
|
|
|
- name: Validate x86-64 host architecture
|
|
ansible.builtin.assert:
|
|
that:
|
|
- host_architecture.stdout | trim in ['x86_64', 'amd64']
|
|
- tool_architecture == 'amd64'
|
|
fail_msg: This profile currently pins x86-64 binaries.
|
|
|
|
- name: Ensure Docker is enabled and running
|
|
ansible.builtin.raw: systemctl enable --now docker
|
|
changed_when: false
|
|
|
|
- name: Create Flatcar k3d directories
|
|
ansible.builtin.raw: >-
|
|
install -d -m 0755 -o {{ k3d_user }} -g {{ k3d_group }}
|
|
{{ k3d_tool_dir }} {{ k3d_workspace }} /home/core/.kube
|
|
|
|
- name: Install pinned k3d
|
|
ansible.builtin.raw: >-
|
|
if [ ! -x {{ k3d_tool_dir }}/k3d ] || [ ! -f {{ k3d_tool_dir }}/.k3d-{{ k3d_version }} ]; then
|
|
curl --fail --location --silent --show-error https://github.com/k3d-io/k3d/releases/download/v{{ k3d_version }}/k3d-linux-{{ tool_architecture }} --output {{ k3d_tool_dir }}/k3d && chmod 0755 {{ k3d_tool_dir }}/k3d &&
|
|
touch {{ k3d_tool_dir }}/.k3d-{{ k3d_version }};
|
|
fi
|
|
|
|
- name: Install pinned kubectl
|
|
ansible.builtin.raw: >-
|
|
if [ ! -x {{ k3d_tool_dir }}/kubectl ] || [ ! -f {{ k3d_tool_dir }}/.kubectl-{{ kubectl_version }} ]; then
|
|
curl --fail --location --silent --show-error https://dl.k8s.io/release/{{ kubectl_version }}/bin/linux/{{ tool_architecture }}/kubectl --output {{ k3d_tool_dir }}/kubectl && chmod 0755 {{ k3d_tool_dir }}/kubectl &&
|
|
touch {{ k3d_tool_dir }}/.kubectl-{{ kubectl_version }};
|
|
fi
|
|
|
|
- name: Download and install pinned Helm
|
|
ansible.builtin.raw: >-
|
|
if [ ! -x {{ k3d_tool_dir }}/helm ] || [ ! -f {{ k3d_tool_dir }}/.helm-{{ helm_version }} ]; then
|
|
curl --fail --location --silent --show-error https://get.helm.sh/helm-{{ helm_version }}-linux-{{ tool_architecture }}.tar.gz --output /tmp/flatcar-k3d-helm.tar.gz &&
|
|
tar -xzf /tmp/flatcar-k3d-helm.tar.gz -C /tmp &&
|
|
install -m 0755 /tmp/linux-amd64/helm {{ k3d_tool_dir }}/helm &&
|
|
touch {{ k3d_tool_dir }}/.helm-{{ helm_version }};
|
|
fi
|
|
|
|
- name: Configure core shell PATH
|
|
ansible.builtin.raw: >-
|
|
grep -Fxq 'export PATH="{{ k3d_tool_dir }}:$HOME/bin:$PATH"' /home/core/.profile ||
|
|
printf '%s\n' 'export PATH="{{ k3d_tool_dir }}:$HOME/bin:$PATH"'
|
|
'export KUBECONFIG="$HOME/.kube/config"' >> /home/core/.profile
|
|
&& chown core:core /home/core/.profile && chmod 0644 /home/core/.profile
|
|
|
|
- name: Copy repository from the Ansible controller
|
|
ansible.posix.synchronize:
|
|
src: "{{ bootstrap_repo_source }}/"
|
|
dest: "{{ k3d_workspace }}/"
|
|
archive: true
|
|
delete: false
|
|
rsync_opts:
|
|
- "--exclude=.git"
|
|
- "--exclude=artifacts"
|
|
delegate_to: localhost
|
|
become: false
|
|
when: bootstrap_repo_url | length == 0
|
|
|
|
- name: Install temporary repository deploy key
|
|
ansible.builtin.raw: >-
|
|
printf '%s' '{{ bootstrap_repo_ssh_private_key | b64encode }}' | base64 -d
|
|
> {{ bootstrap_repo_ssh_private_key_path }} &&
|
|
chmod 0600 {{ bootstrap_repo_ssh_private_key_path }}
|
|
no_log: true
|
|
when:
|
|
- bootstrap_repo_url | length > 0
|
|
- bootstrap_repo_ssh_private_key | length > 0
|
|
|
|
- name: Clone or update the repository on the host
|
|
ansible.builtin.raw: >-
|
|
if [ -d {{ k3d_workspace }}/.git ]; then
|
|
git -C {{ k3d_workspace }} fetch --prune origin {{ bootstrap_repo_ref }} &&
|
|
git -C {{ k3d_workspace }} checkout {{ bootstrap_repo_ref }} &&
|
|
git -C {{ k3d_workspace }} reset --hard origin/{{ bootstrap_repo_ref }};
|
|
else
|
|
GIT_SSH_COMMAND="ssh -i {{ bootstrap_repo_ssh_private_key_path }} -o StrictHostKeyChecking=accept-new"
|
|
git clone --branch {{ bootstrap_repo_ref }} {{ bootstrap_repo_url }} {{ k3d_workspace }};
|
|
fi
|
|
no_log: "{{ bootstrap_repo_ssh_private_key | length > 0 }}"
|
|
when: bootstrap_repo_url | length > 0
|
|
|
|
- name: Remove temporary repository deploy key
|
|
ansible.builtin.raw: rm -f {{ bootstrap_repo_ssh_private_key_path }}
|
|
when:
|
|
- bootstrap_repo_url | length > 0
|
|
- bootstrap_repo_ssh_private_key | length > 0
|
|
|
|
- name: Check whether the k3d cluster already exists
|
|
ansible.builtin.raw: "{{ k3d_tool_dir }}/k3d cluster list"
|
|
register: k3d_cluster_list
|
|
changed_when: false
|
|
|
|
- name: Configure the Cilium profile API certificate SAN
|
|
ansible.builtin.raw: >-
|
|
sed -i
|
|
-e 's/K3D_EXTERNAL_API_SERVER_IP/{{ kubeconfig_server_host }}/g'
|
|
-e 's/K3D_INTERNAL_API_SERVER_IP/{{ cilium_k8s_service_host }}/g'
|
|
{{ k3d_workspace }}/local-quickstart/{{ k3d_config_source | basename }}
|
|
when:
|
|
- cilium_enabled | bool
|
|
- cilium_k8s_service_host | default('') | length > 0
|
|
- k3d_cluster_name not in k3d_cluster_list.stdout
|
|
|
|
- name: Create the k3d cluster
|
|
ansible.builtin.raw: >-
|
|
{{ k3d_tool_dir }}/k3d cluster create
|
|
--config {{ k3d_workspace }}/local-quickstart/{{ k3d_config_source | basename }}
|
|
--wait --timeout 180s
|
|
become_user: "{{ k3d_user }}"
|
|
when: k3d_cluster_name not in k3d_cluster_list.stdout
|
|
|
|
- name: Write the cluster kubeconfig for the core user
|
|
ansible.builtin.raw: >-
|
|
{{ k3d_tool_dir }}/k3d kubeconfig get {{ k3d_cluster_name }}
|
|
> /home/core/.kube/config && chmod 0600 /home/core/.kube/config
|
|
become_user: "{{ k3d_user }}"
|
|
|
|
- name: Verify Kubernetes nodes are Ready for the standard profile
|
|
ansible.builtin.raw: "{{ k3d_tool_dir }}/kubectl get nodes --no-headers"
|
|
become_user: "{{ k3d_user }}"
|
|
register: k3d_nodes
|
|
changed_when: false
|
|
when: not (cilium_enabled | bool)
|
|
retries: 12
|
|
delay: 10
|
|
until:
|
|
- k3d_nodes.rc == 0
|
|
- k3d_nodes.stdout is search(' Ready ')
|
|
|
|
- name: Verify Kubernetes API and node objects for the Cilium profile
|
|
ansible.builtin.raw: "{{ k3d_tool_dir }}/kubectl get nodes --no-headers"
|
|
become_user: "{{ k3d_user }}"
|
|
register: k3d_nodes_cilium
|
|
changed_when: false
|
|
when: cilium_enabled | bool
|
|
retries: 12
|
|
delay: 10
|
|
until:
|
|
- k3d_nodes_cilium.rc == 0
|
|
- k3d_nodes_cilium.stdout | trim | length > 0
|
|
|
|
- name: Configure reachable upstream DNS servers for CoreDNS
|
|
ansible.builtin.raw: >-
|
|
{{ k3d_tool_dir }}/kubectl -n kube-system create configmap coredns-custom
|
|
--from-literal=upstream.override='forward . {{ (k3d_dns_servers | string | from_yaml) | join(' ') }}'
|
|
--dry-run=client -o yaml |
|
|
{{ k3d_tool_dir }}/kubectl apply -f -
|
|
become_user: "{{ k3d_user }}"
|
|
when: k3d_dns_servers | length > 0
|
|
|
|
- name: Restart CoreDNS after changing upstream resolvers
|
|
ansible.builtin.raw: >-
|
|
{{ k3d_tool_dir }}/kubectl -n kube-system rollout restart deployment/coredns &&
|
|
{{ k3d_tool_dir }}/kubectl -n kube-system rollout status deployment/coredns
|
|
--timeout=120s
|
|
become_user: "{{ k3d_user }}"
|
|
when: k3d_dns_servers | length > 0
|
|
|
|
- name: Ensure local kubeconfig artifact directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ kubeconfig_artifact_dir }}"
|
|
state: directory
|
|
mode: '0700'
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|
|
when: kubeconfig_fetch_enabled | bool
|
|
|
|
- name: Fetch kubeconfig artifact to the Ansible controller
|
|
ansible.posix.synchronize:
|
|
src: /home/core/.kube/config
|
|
dest: "{{ kubeconfig_artifact_dir }}/{{ inventory_hostname }}-kubeconfig"
|
|
mode: pull
|
|
archive: true
|
|
rsync_opts:
|
|
- "--checksum"
|
|
delegate_to: localhost
|
|
become: false
|
|
when: kubeconfig_fetch_enabled | bool
|
|
|
|
- name: Replace the k3d wildcard API address in the local artifact
|
|
ansible.builtin.replace:
|
|
path: "{{ kubeconfig_artifact_dir }}/{{ inventory_hostname }}-kubeconfig"
|
|
regexp: '(?m)^(\s+server:\s+https://)0\.0\.0\.0(:[0-9]+\s*)$'
|
|
replace: '\g<1>{{ kubeconfig_server_host }}\g<2>'
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Read the rewritten local kubeconfig server endpoint
|
|
ansible.builtin.command:
|
|
cmd: >-
|
|
kubectl config view
|
|
--kubeconfig {{ kubeconfig_artifact_dir }}/{{ inventory_hostname }}-kubeconfig
|
|
--minify -o jsonpath={.clusters[0].cluster.server}
|
|
register: rewritten_kubeconfig_server
|
|
changed_when: false
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Require a reachable host address in the local kubeconfig artifact
|
|
ansible.builtin.assert:
|
|
that:
|
|
- rewritten_kubeconfig_server.stdout | trim is match('^https://' ~ (kubeconfig_server_host | regex_escape) ~ ':[0-9]+$')
|
|
- rewritten_kubeconfig_server.stdout | trim is not search('0\.0\.0\.0')
|
|
fail_msg: >-
|
|
The fetched kubeconfig still points to an unusable API address:
|
|
{{ rewritten_kubeconfig_server.stdout | trim }}
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Ensure the default kubeconfig directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ kubeconfig_default_path | dirname }}"
|
|
state: directory
|
|
mode: '0700'
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Merge the fetched kubeconfig into the operator default
|
|
ansible.builtin.command:
|
|
cmd: kubectl config view --flatten
|
|
environment:
|
|
# Put the freshly fetched artifact first so it overrides an older entry
|
|
# with the same cluster and context name.
|
|
KUBECONFIG: "{{ kubeconfig_artifact_dir }}/{{ inventory_hostname }}-kubeconfig:{{ kubeconfig_default_path }}"
|
|
register: merged_kubeconfig
|
|
changed_when: false
|
|
delegate_to: localhost
|
|
become: false
|
|
no_log: true
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Install the merged kubeconfig as the operator default
|
|
ansible.builtin.copy:
|
|
content: "{{ merged_kubeconfig.stdout }}"
|
|
dest: "{{ kubeconfig_default_path }}"
|
|
mode: '0600'
|
|
delegate_to: localhost
|
|
become: false
|
|
no_log: true
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Select the bootstrapped cluster context
|
|
ansible.builtin.command:
|
|
cmd: kubectl config use-context {{ kubeconfig_context_name }} --kubeconfig {{ kubeconfig_default_path }}
|
|
register: selected_kubeconfig_context
|
|
changed_when: false
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Verify the selected kubeconfig context
|
|
ansible.builtin.command:
|
|
cmd: kubectl config current-context --kubeconfig {{ kubeconfig_default_path }}
|
|
register: selected_kubeconfig_context_check
|
|
changed_when: false
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|
|
|
|
- name: Require the expected bootstrapped context to be current
|
|
ansible.builtin.assert:
|
|
that:
|
|
- selected_kubeconfig_context_check.stdout | trim == kubeconfig_context_name
|
|
fail_msg: >-
|
|
The default kubeconfig context was not changed to
|
|
{{ kubeconfig_context_name }}.
|
|
delegate_to: localhost
|
|
become: false
|
|
when:
|
|
- kubeconfig_fetch_enabled | bool
|
|
- kubeconfig_import_enabled | bool
|