Rancher is working, including Vaultwarden password

This commit is contained in:
Jeroen Vermeulen 2023-09-04 18:09:08 +02:00
parent 15d866b253
commit 08f36a74f8
No known key found for this signature in database
14 changed files with 276 additions and 64 deletions

6
playbook.yml Normal file
View File

@ -0,0 +1,6 @@
---
- name: Include playbook talos
ansible.builtin.import_playbook: talos.yml
- name: Include playbook services
ansible.builtin.import_playbook: services.yml

View File

@ -0,0 +1,3 @@
---
dependencies:
- role: common

View File

@ -0,0 +1,44 @@
---
- name: Helm add Jetstack repo
delegate_to: "{{ kubectl_host }}"
run_once: true
kubernetes.core.helm_repository:
name: jetstack
repo_url: "https://charts.jetstack.io"
- name: Helm deploy Jetstack Cert-Manager
delegate_to: "{{ kubectl_host }}"
kubernetes.core.helm:
kubeconfig: "{{ kubeconfig }}"
chart_ref: jetstack/cert-manager
release_name: cert-manager
release_namespace: cert-manager
create_namespace: true
wait: true
# https://github.com/cert-manager/cert-manager/blob/master/deploy/charts/cert-manager/values.yaml
values:
installCRDs: true
startupapicheck:
timeout: 10m
- name: Deploy cluster issuer
delegate_to: "{{ kubectl_host }}"
kubernetes.core.k8s:
kubeconfig: "{{ kubeconfig }}"
resource_definition:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: default
spec:
acme:
email: "{{ letsencrypt_email }}"
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-private-key
solvers:
- http01:
ingress:
class: traefik

View File

@ -7,11 +7,13 @@ talos_generic_config_dir: "{{ ansible_root_dir }}/configs/talos"
talos_cluster_config_dir: "{{ ansible_root_dir }}/configs/{{ cluster_name }}"
talos_cluster_secrets_file: "{{ talos_cluster_config_dir }}/talos-secrets.yaml"
talos_control_lb_hostname: "control.{{ cluster_name }}"
talos_workers_lb_hostname: "workers.{{ cluster_name }}"
talos_node_config_file: "{{ talos_cluster_config_dir }}/talos-{{ inventory_hostname }}.yaml"
talosconfig: "{{ talos_cluster_config_dir }}/talosconfig.yaml"
kubeconfig: "{{ talos_cluster_config_dir }}/kubeconfig.yaml"
talos_image_version: v1.4.7
kubectl_host: localhost
talosctl_host: localhost
ingress_lb_hostname: "workers.{{ cluster_name }}"
ingress_ips: [] # One or more IPs must be defined for first cluster node using Inventory
rancher_hostname: "rancher.{{ cluster_name }}"
letsencrypt_email: "jeroen@deovero.com"

View File

@ -4,7 +4,7 @@
delegate_to: "{{ kubectl_host }}"
kubernetes.core.k8s:
kubeconfig: "{{ kubeconfig }}"
definition:
resource_definition:
kind: Namespace
metadata:
name: metallb-system
@ -24,8 +24,8 @@
delegate_to: "{{ kubectl_host }}"
kubernetes.core.helm:
kubeconfig: "{{ kubeconfig }}"
name: metallb
chart_ref: metallb/metallb
release_name: metallb
release_namespace: metallb-system
create_namespace: false
wait: true
@ -35,7 +35,7 @@
delegate_to: "{{ kubectl_host }}"
kubernetes.core.k8s:
kubeconfig: "{{ kubeconfig }}"
definition:
resource_definition:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
@ -48,7 +48,7 @@
delegate_to: "{{ kubectl_host }}"
kubernetes.core.k8s:
kubeconfig: "{{ kubeconfig }}"
definition:
resource_definition:
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:

View File

@ -0,0 +1,3 @@
---
dependencies:
- role: common

View File

@ -0,0 +1,164 @@
---
- name: Helm add Rancher repo
delegate_to: "{{ kubectl_host }}"
run_once: true
kubernetes.core.helm_repository:
name: rancher
repo_url: "https://releases.rancher.com/server-charts/latest"
- name: Verify Rancher hostname
delegate_to: "{{ kubectl_host }}"
ansible.builtin.set_fact:
_dig_rancher_hostname: "{{ lookup('community.general.dig', '{{ rancher_hostname }}.', '@1.1.1.1')}}"
- name: "Verify Rancher hostname resolves: {{ rancher_hostname }}"
ansible.builtin.assert:
that: "_dig_rancher_hostname == '{{ ingress_ips[0] }}'"
quiet: true
- name: Helm deploy Rancher
delegate_to: "{{ kubectl_host }}"
kubernetes.core.helm:
kubeconfig: "{{ kubeconfig }}"
chart_ref: rancher/rancher
release_name: rancher
release_namespace: cattle-system
create_namespace: true
wait: true
# https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options
# https://github.com/rancher/rancher/blob/release/v2.8/chart/values.yaml
values:
hostname: "{{ rancher_hostname }}"
replicas: 2
ingress:
tls:
source: letsEncrypt
letsEncrypt:
email: "{{ letsencrypt_email }}"
ingress:
class: traefik
global:
cattle:
psp:
enable: false
- name: Set name for Bitwarden secret
ansible.builtin.set_fact:
_bitwarden_password_item_name: "Rancher {{ cluster_name }}"
- name: "Get item from Bitwarden"
ansible.builtin.set_fact:
_rancher_password_item: >-
{{ lookup('community.general.bitwarden', '{{ _bitwarden_password_item_name }}', field='password') }}
- name: "Get password from Bitwarden"
when: "{{ _rancher_password_item | length }}"
ansible.builtin.set_fact:
_rancher_password: "{{ _rancher_password_item[0] }}"
- name: When Bitwarden item not found
when: "not _rancher_password_item | length"
block:
- name: Get Rancher bootstrap secret
delegate_to: "{{ kubectl_host }}"
kubernetes.core.k8s_info:
kubeconfig: "{{ kubeconfig }}"
kind: Secret
name: bootstrap-secret
namespace: cattle-system
register: _rancher_bootstrap_secret
- name: Set rancher password fact
ansible.builtin.set_fact:
_rancher_bootstrap_password: "{{ _rancher_bootstrap_secret.resources[0].data.bootstrapPassword | ansible.builtin.b64decode }}"
- name: Create random password
ansible.builtin.set_fact:
_rancher_password: "{{ lookup('ansible.builtin.password', '/dev/null') }}"
- name: Create password item
ansible.builtin.set_fact:
_bitwarden_password_item: {
object: "item",
folderId: "b1be156c-76b0-4ab6-bdd3-4181aca59cc8",
# organizationId: "47551728-68ca-4267-acc7-c71898da28d3",
type: 1,
name: "{{ _bitwarden_password_item_name }}",
login: {
uris: [
{
"match": null,
"uri": "https://{{ rancher_hostname }}/dashboard/"
}
],
username: "admin",
password: "{{ _rancher_password }}",
},
collectionIds": [
"82f4e18b-9de9-4d80-8f5c-2a4911b7f729"
],
}
- name: Create BW item
delegate_to: localhost
ansible.builtin.command:
cmd: "bw create item {{ _bitwarden_password_item | ansible.builtin.to_json | ansible.builtin.b64encode }}"
- name: Rancher login
delegate_to: "{{ kubectl_host }}"
ansible.builtin.uri:
url: "https://{{ rancher_hostname }}/v3-public/localProviders/local?action=login"
method: POST
body_format: json
body:
username: admin
password: "{{ _rancher_bootstrap_password }}"
status_code: [201]
register: _rancher_pwchange_login
- name: Rancher change password
delegate_to: "{{ kubectl_host }}"
ansible.builtin.uri:
url: "https://{{ rancher_hostname }}/v3/users?action=changepassword"
method: POST
headers:
Cookie: "R_SESS={{ _rancher_pwchange_login.json.token }}"
body_format: json
body:
currentPassword: "{{ _rancher_bootstrap_password }}"
newPassword: "{{ _rancher_password }}"
status_code: [200]
- name: Rancher logout
delegate_to: "{{ kubectl_host }}"
ansible.builtin.uri:
url: "https://{{ rancher_hostname }}/v3/tokens?action=logout"
method: POST
headers:
Cookie: "R_SESS={{ _rancher_pwchange_login.json.token }}"
status_code: [200]
- name: Rancher login
delegate_to: "{{ kubectl_host }}"
ansible.builtin.uri:
url: "https://{{ rancher_hostname }}/v3-public/localProviders/local?action=login"
method: POST
body_format: json
body:
username: admin
password: "{{ _rancher_password }}"
status_code: [201]
register: _rancher_login
- ansible.builtin.debug:
var: _rancher_login
- name: Rancher logout
delegate_to: "{{ kubectl_host }}"
ansible.builtin.uri:
url: "https://{{ rancher_hostname }}/v3/tokens?action=logout"
method: POST
headers:
Cookie: "R_SESS={{ _rancher_login.json.token }}"
status_code: [200]

View File

@ -18,6 +18,10 @@
changed_when: true
environment:
TALOSCONFIG: "{{ talosconfig }}"
register: _talosctl_bootstrap
until: "_talosctl_bootstrap is not failed"
retries: 10
delay: 5
notify: Talos wait for health
- name: Flush handlers
@ -46,21 +50,3 @@
- name: Show Kubectl get nodes output
ansible.builtin.debug:
var: _kubectl_get_nodes.stdout_lines
# - name: Get nodes
# when: 'first_node | default(false)"
# delegate_to: "{{ kubectl_host }}"
# become: no
# kubernetes.core.k8s_info:
# kind: Node
# kubeconfig: "{{ kubeconfig }}"
# register: _k8s_nodes
# - name: Show nodes
# when: "first_node | default(false)"
# ansible.builtin.debug:
# msg: "{{ _k8s_node.metadata.name }}"
# loop: "{{ _k8s_nodes.resources }}"
# loop_control:
# loop_var: _k8s_node
# label: "{{ _k8s_node.metadata.name }}"

View File

@ -1,24 +0,0 @@
---
- name: Apply Talos node config
delegate_to: "{{ talosctl_host }}"
become: no
ansible.builtin.command:
cmd: >-
talosctl apply-config
--file '{{ talos_node_config_file }}'
--nodes '{{ ansible_remote }}'
--endpoints '{{ ansible_remote }}'
--mode auto
{% if talos_machine_status.spec.stage == 'maintenance' %} --insecure{% endif %}
changed_when: true
environment:
TALOSCONFIG: "{{ talosconfig }}"
- name: Wait for Talos port 50000
delegate_to: "{{ talosctl_host }}"
become: no
ansible.builtin.wait_for:
host: "{{ ansible_remote }}"
port: 50000
delay: 5

View File

@ -10,5 +10,25 @@
- name: Import talos_machine_status tasks
ansible.builtin.import_tasks: "{{ role_path }}/../../shared/tasks/talos_machine_status.yml"
- name: Import apply_node_config tasks
ansible.builtin.import_tasks: apply_node_config.yml
- name: Apply Talos node config
delegate_to: "{{ talosctl_host }}"
become: no
ansible.builtin.command:
cmd: >-
talosctl apply-config
--file '{{ talos_node_config_file }}'
--nodes '{{ ansible_remote }}'
--endpoints '{{ ansible_remote }}'
--mode auto
{% if talos_machine_status.spec.stage == 'maintenance' %} --insecure{% endif %}
changed_when: true
environment:
TALOSCONFIG: "{{ talosconfig }}"
- name: Wait for Talos port 50000
delegate_to: "{{ talosctl_host }}"
become: no
ansible.builtin.wait_for:
host: "{{ ansible_remote }}"
port: 50000
delay: 5

View File

@ -1,13 +1,18 @@
---
- name: Import talos_machine_status tasks
ansible.builtin.import_tasks: "{{ role_path }}/../../shared/tasks/talos_machine_status.yml"
- name: Reset Talos
# You can't execute this on nodes in Maintenance mode, they are already 'reset'.
when: "talos_machine_status.spec.stage != 'maintenance'"
delegate_to: "{{ talosctl_host }}"
become: no
ansible.builtin.command:
cmd: >-
talosctl reset
--graceful=false
--wait=false
--wait=true
--reboot
--endpoints '{{ ansible_remote }}'
--nodes '{{ ansible_remote }}'
@ -21,4 +26,3 @@
ansible.builtin.wait_for:
host: "{{ ansible_remote }}"
port: 50000
delay: 10

View File

@ -11,12 +11,12 @@
delegate_to: "{{ kubectl_host }}"
kubernetes.core.helm:
kubeconfig: "{{ kubeconfig }}"
name: metallb
chart_ref: traefik/traefik
release_name: metallb
release_namespace: traefik
create_namespace: true
wait: true
# https://github.com/metallb/metallb/blob/main/charts/metallb/values.yaml
# https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml
values:
deployment:
kind: DaemonSet
@ -28,7 +28,7 @@
externalTrafficPolicy: Local
loadBalancerIP: "{{ ingress_ips[0] }}"
annotations:
external-dns.alpha.kubernetes.io/hostname: "{{ talos_workers_lb_hostname }}"
external-dns.alpha.kubernetes.io/hostname: "{{ ingress_lb_hostname }}"
ports:
web:
proxyProtocol:

13
services.yml Normal file
View File

@ -0,0 +1,13 @@
---
# Playbook Services Install
- name: Install services on K8S
become: no
gather_facts: false
hosts:
- talos_first_nodes
roles:
- role: metallb
- role: traefik
- role: cert-manager
- role: rancher

View File

@ -1,5 +1,5 @@
---
# Playbook Kubernetes Install
# Playbook Talos Install
- name: Talos configs
become: no
@ -17,12 +17,3 @@
- talos_first_nodes
roles:
- role: talos_bootstrap
- name: Install services on K8S
become: no
gather_facts: false
hosts:
- talos_first_nodes
roles:
- role: metallb
- role: traefik