Files
kubernetes-security-baselin…/ansible
swaphb 6e7f5b39fb
Kube-bench CIS scan / Scan ephemeral K3s cluster (push) Successful in 59s
make falco alerting opt in
2026-08-16 21:36:09 -04:00
..
2026-08-16 21:36:09 -04:00
2026-08-09 19:52:19 -04:00
2026-08-16 21:36:09 -04:00

Ansible bootstrap paths

The repository has two separate Ansible paths:

  • bootstrap-k3s.yml configures a production-style Flatcar K3s server.
  • bootstrap-flatcar-k3d.yml configures the dedicated Flatcar k3d test host, bootstraps ArgoCD, and optionally installs Cilium.

The Flatcar k3d path is idempotent and keeps the standard profile as the default. Cilium is enabled only when the inventory explicitly sets cilium_enabled: true and selects a kube-proxy-free cluster configuration.

Flatcar does not include Python in the immutable host OS. The role therefore uses Ansible raw tasks for host operations and ansible.posix.synchronize for repository and kubeconfig transfer. Install the collection before use:

ansible-galaxy collection install -r ansible/requirements.yml

Flatcar k3d bootstrap

Copy the example inventory and replace the host, SSH key, and optional API endpoint values:

cp ansible/inventory.flatcar-k3d.example.yml ansible/inventory.flatcar-k3d.yml
ansible-playbook \
  -i ansible/inventory.flatcar-k3d.yml \
  ansible/bootstrap-flatcar-k3d.yml

The playbook installs pinned k3d, kubectl, and Helm binaries, starts Docker, creates the k3d cluster, writes the core user's kubeconfig, fetches a copy into the local artifacts/ directory, merges that config into the operator's default ~/.kube/config, selects the new context as current, installs ArgoCD from a pinned official manifest, and applies the GitOps root Application from deployments/argocd/. The merge preserves existing contexts and the playbook verifies the selected context before continuing.

Set kubeconfig_import_enabled: false when the fetched artifact should not change the operator's default kubeconfig.

By default the playbook copies the current repository from the Ansible controller to the host. For a private repository, set bootstrap_repo_url, bootstrap_repo_ref, and provide bootstrap_repo_ssh_private_key through Ansible Vault. The private key task is marked no_log and is removed after the checkout.

When k3d exports its kubeconfig, it may use 0.0.0.0 as the API server host. Ansible rewrites that host to kubeconfig_server_host, which defaults to the Flatcar host address, while preserving the dynamically assigned API port. The rewritten endpoint is verified before the config is merged into the default kubeconfig.

For the optional Cilium path, set these variables in the inventory:

cilium_enabled: true
cilium_profile: k3d
k3d_config_source: "{{ playbook_dir }}/../local-quickstart/k3d-cilium-cluster-config.yaml"
cilium_k8s_service_host: 192.168.60.252
cilium_k8s_service_port: 0

The Cilium role selects the shared values from deployments/cilium/values/common.yaml and the profile from deployments/cilium/values/profiles/{{ cilium_profile }}.yaml. Supported profiles are k3d and flatcar-k3s. It refuses to proceed if a kube-proxy DaemonSet is present, derives the dynamically published k3d API port from the new cluster's kubeconfig, passes the API endpoint explicitly to Helm, and waits for the Cilium DaemonSet.

Use cilium_profile: flatcar-k3s for a dedicated VM deployment. Review the profile's routing assumptions and provide a stable control-plane API address. The dedicated VM profile defaults to Geneve tunneling. Native routing should only be selected when the VM network routes the pod CIDR between nodes.

The playbook does not create Slack or Discord credentials by default. The opt-in falco_alerting role enables Slack forwarding only when supplied with a Vault-protected webhook value.

Store these variables in an Ansible Vault file:

falco_alerting_enabled: true
falco_slack_webhook_url: https://hooks.slack.com/services/REPLACE/ME

Then run the bootstrap with --ask-vault-pass -e @ansible/vars/falco-alerting.vault.yml. The role creates the falco-alerting Secret without logging its value, applies the optional Falcosidekick ArgoCD Application, and lets ArgoCD reconcile the deployment. If the toggle is false, the role removes the optional Application and related resources.

If CoreDNS cannot resolve external names from a nested Docker network, set k3d_dns_servers to DNS servers reachable from the Flatcar host. Ansible creates the supported K3s coredns-custom ConfigMap and restarts CoreDNS so ArgoCD can resolve the Git server and Falcosidekick can resolve its webhook.

Validate the playbook before connecting to a host:

ANSIBLE_LOCAL_TEMP=/tmp/k8s-baseline-ansible-tmp \
  ansible-playbook --syntax-check \
  -i ansible/inventory.flatcar-k3d.example.yml \
  ansible/bootstrap-flatcar-k3d.yml

Production-style K3s bootstrap

The existing production-style path applies a host baseline and installs a pinned K3s server. It is intentionally separate from the local k3d path so the portfolio can run without cloud credentials.

cp inventory.example.yml inventory.yml
# Replace the Terraform public IP and local SSH key path.
ansible-playbook -i inventory.yml bootstrap-k3s.yml

Before production use, review the pinned K3s version and extend the playbook for your organizations OS baseline, firewall model, HA topology, and secret management. RKE2 can replace K3s here if the target environment requires it.