commit 7dda2e1fdc1c8007f5cb7f6b543562149f246f63 Author: srw Date: Thu Jun 6 20:05:18 2024 +0000 prune old address, add basic template files diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0457da1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +vault-pass.gpg-* +roles/* +!roles/requirements.yml diff --git a/.vault/vault-keys b/.vault/vault-keys new file mode 100644 index 0000000..9dddb9f --- /dev/null +++ b/.vault/vault-keys @@ -0,0 +1,4 @@ +D749E2966193DF63 +EE3E0A7A87192BB7 +3C8D0C7EF49AB5A3 +388DD8D74903017E diff --git a/.vault/vault-open.sh b/.vault/vault-open.sh new file mode 100755 index 0000000..10a6372 --- /dev/null +++ b/.vault/vault-open.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +VAULT_PATH=$(dirname "$(realpath "$0")") +VAULT_CMD="gpg --quiet --batch --use-agent --decrypt" +VAULT_KEY_FILE=vault-pass.gpg + +# define the password in a static env +# VAULT_KEY + +if [ -n "$VAULT_KEY" ]; then + echo "$VAULT_KEY" +else + $VAULT_CMD "$VAULT_PATH/$VAULT_KEY_FILE" +fi diff --git a/.vault/vault-pass.gpg b/.vault/vault-pass.gpg new file mode 100644 index 0000000..7b6b4dd Binary files /dev/null and b/.vault/vault-pass.gpg differ diff --git a/.vault/vault-rekey.sh b/.vault/vault-rekey.sh new file mode 100755 index 0000000..531251f --- /dev/null +++ b/.vault/vault-rekey.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +DATE=$(date "+%Y%m%d-%s") + +# default key locations +TARGET=".vault/vault-pass.gpg" +KEYFILE=".vault/vault-keys" + +# read keys from here, overridden by KEYFILE +#KEYS="XXX" + +check_input() +{ + if [ -z "$KEYS" ]; then + if [ -z "$1" ]; then + echo >&2 "supply at least one key ID" + exit 1 + fi + fi +} + +if [ -f "$KEYFILE" ]; then + KEYS="$(cat $KEYFILE | tr '\n' ' ')" +fi + +if [ -f "$1" ]; then + TARGET=$1 + check_input "$2" + shift +else + if [ -f "$TARGET" ]; then + check_input "$1" + else + echo >&2 "default target not found: $TARGET" + exit 2 + fi +fi + +# backup existing vault +mv "$TARGET" "$TARGET-$DATE" + +# build key list +# loop twice once for the array and once for the flat var to maintain sh compat +for KEY in $KEYS; do KEY_LIST=$KEY_LIST"-r $KEY "; done +for KEY in "$@"; do KEY_LIST=$KEY_LIST"-r $KEY "; done + +# rekey target file, ignore shellcheck globbing/word splitting warning +gpg -q -d "$TARGET-$DATE" | gpg -q -e --trust-model always $KEY_LIST -o "$TARGET" + +# verification +#md5sum "$TARGET-$DATE" +#md5sum "$TARGET" diff --git a/README.md b/README.md new file mode 100644 index 0000000..35bc98e --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# Ansible Playbook to setup a simple k8s cluster + +Checkout repo and switch to the directorty `~/lx-cad-deploy` + +Install ansible via virtual env + +``` +sudo apt install python3-pip python3.10-venv +python3.10 -m venv ~/.local/venv/ansible +source ~/.local/venv/ansible/bin/activate +pip install ansible +ansible --version +``` + +Install required roles: + +``` +ansible-galaxy install -f -p roles -r roles/requirements.yml +``` + +Generate token for the cluster, this assumes ansible vault has been setup + +``` +./roles/k8s/files/token-vault.sh ./group_vars/lx_cad/k8s-vault.yml +``` + +Configure firewalld and nginx for hosts + +``` +ansible-playbook -i hosts site.yml --tags=firewalld,nginx +``` + +Install Stack Orchestrator for control hosts + +``` +ansible-playbook -i hosts site.yml --tags=so --limit=so +``` + +Deploy k8s + +``` +ansible-playbook -i hosts site.yml --tags=k8s --limit=lx_cad +``` + +Install k8s helper tools + +``` +sudo ~/lx-cad-deploy/roles/k8s/files/get-kube-tools.sh +``` + +Verify cluster creation + +``` +kubie ctx lx-cad +kubectl get nodes -o wide +``` + +DNS Secret example + +``` +apiVersion: v1 +data: + access-token: XXX +kind: Secret +metadata: + name: someprovider-dns + namespace: cert-manager +``` diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..5d3b69a --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,3 @@ +[defaults] +roles_path = roles:galaxy-roles:git-roles:ansible-roles:~/.ansible/roles +vault_password_file = .vault/vault-open.sh diff --git a/files/manifests/digitalocean-dns.yaml b/files/manifests/digitalocean-dns.yaml new file mode 100644 index 0000000..4d469f8 --- /dev/null +++ b/files/manifests/digitalocean-dns.yaml @@ -0,0 +1,16 @@ +$ANSIBLE_VAULT;1.1;AES256 +32383162626163663734653236646538626464643665323334666363306662363434346133653737 +3766373965626437376630303837663339383664643466300a336463366335636634336437303036 +32626138646662633337663037393538336438643363303962326263656636316336346462643937 +6337363463626265630a663964386638633133613465363436376533346336333066663664363062 +65333864353338656437333762313937376538376634383438643134313266366236393039376131 +35646533353539633436343435316465386534646663316234336263363163343463626632663837 +66633432376136323961336437613465303635303966343530383162653766373736333661386163 +30303233333939626537303631313532373130363866306165343732653064643866393933323230 +31373035653332363961343464613134626464643733313666333861623961373264303462633334 +63653638356666656163343266353133396236313231643664313764663761363634643063323466 +36623266393166316138343239393663393739666266653730323766643566343936386436666164 +30616637656563626634306634336631613564396234613836396537636363643466323762393166 +33623534613462306130356631626265373462343065333132666439623333663135336437323536 +36303131386135333763356565323962666233353263353331653065333435613138343939393530 +633664316538643432303731366233653831 diff --git a/files/manifests/wildcard-pwa-audubon.yaml b/files/manifests/wildcard-pwa-audubon.yaml new file mode 100644 index 0000000..b048501 --- /dev/null +++ b/files/manifests/wildcard-pwa-audubon.yaml @@ -0,0 +1,15 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: pwa.audubon.app + namespace: default +spec: + secretName: pwa.audubon.app + issuerRef: + name: letsencrypt-prod-wild + kind: ClusterIssuer + group: cert-manager.io + commonName: "*.pwa.audubon.app" + dnsNames: + - ".pwa.audubon.app" + - "*.pwa.audubon.app" diff --git a/group_vars/all/nginx-vault.yml b/group_vars/all/nginx-vault.yml new file mode 100644 index 0000000..9bad4e6 --- /dev/null +++ b/group_vars/all/nginx-vault.yml @@ -0,0 +1,7 @@ +$ANSIBLE_VAULT;1.1;AES256 +61643936333265303166353936373164393663353565343136313838663932646663653165393262 +3435356136353463633330333861666638613831306439350a636462346339343465343864363233 +63643831653462383462623639653439336239313831383333326135303662363830326235396666 +3164653535666539390a356133333438306332383537616331336138333161643361393462653037 +32626534346339303662643138336639646530626561393834303663626464646364616433633263 +3233303765316363373061376262366239633864353437383136 diff --git a/group_vars/lx_cad/k8s-vault.yml b/group_vars/lx_cad/k8s-vault.yml new file mode 100644 index 0000000..f939c98 --- /dev/null +++ b/group_vars/lx_cad/k8s-vault.yml @@ -0,0 +1,8 @@ +$ANSIBLE_VAULT;1.1;AES256 +35636161616230343863626538626535303366383363623336636166343331626664326230626661 +3937353665346130663263653132393634333736343962610a343732303062353436636232653731 +65393839356235336434343038373530313136306563656633346561633839656238613838616634 +3537363938303830340a373435396561656433303632366132343765323139653930316531356337 +39353865386535633339306537646465336438353030616631326136636138336332373965646439 +65666530666263326165653162373633306139613266616364616435626138666433326365333334 +333662376231636163356430636438656565 diff --git a/group_vars/lx_cad/k8s.yml b/group_vars/lx_cad/k8s.yml new file mode 100644 index 0000000..3d0ae10 --- /dev/null +++ b/group_vars/lx_cad/k8s.yml @@ -0,0 +1,39 @@ +--- +k8s_cluster_name: lx-cad +k8s_cluster_url: lx-cad-cluster-control.audubon.app +k8s_taint_servers: true + +k8s_manifests: + - name: cert-manager + url: https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.yaml + + # issuer for basic http certs + - name: letsencrypt-prod + type: template + source: shared/clusterissuer-acme.yaml + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - type: http + ingress: nginx + + # issuer for wildcard dns certs + - name: letsencrypt-prod-wild + type: template + source: shared/clusterissuer-acme.yaml + server: https://acme-v02.api.letsencrypt.org/directory + solvers: + - type: dns + provider: digitalocean + tokenref: tokenSecretRef + secret_name: digitalocean-dns + secret_key: access-token + + # initiate wildcard cert + - name: pwa.audubon.app + type: file + source: wildcard-pwa-audubon.yaml + +k8s_secrets: + - name: digitalocean-dns + type: file + source: secret-digitalocean-dns.yaml diff --git a/host_vars/lx-cad-cluster-control/firewalld.yml b/host_vars/lx-cad-cluster-control/firewalld.yml new file mode 100644 index 0000000..eb0aeed --- /dev/null +++ b/host_vars/lx-cad-cluster-control/firewalld.yml @@ -0,0 +1,15 @@ +--- +firewalld_add: + - name: public + interfaces: + - enp9s0 + services: + - http + - https + + - name: trusted + sources: + - 10.42.0.0/16 + - 10.43.0.0/16 + - 23.111.78.182/32 + - 23.111.69.218/32 diff --git a/host_vars/lx-cad-cluster-worker/firewalld.yml b/host_vars/lx-cad-cluster-worker/firewalld.yml new file mode 100644 index 0000000..71af218 --- /dev/null +++ b/host_vars/lx-cad-cluster-worker/firewalld.yml @@ -0,0 +1,15 @@ +--- +firewalld_add: + - name: public + interfaces: + - enp9s0 + services: + - http + - https + + - name: trusted + sources: + - 10.42.0.0/16 + - 10.43.0.0/16 + - 23.111.78.179/32 + - 23.111.69.218/32 diff --git a/host_vars/lx-daemon/firewalld.yml b/host_vars/lx-daemon/firewalld.yml new file mode 100644 index 0000000..62c4493 --- /dev/null +++ b/host_vars/lx-daemon/firewalld.yml @@ -0,0 +1,17 @@ +--- +firewalld_add: + - name: public + interfaces: + - ens3 + services: + - http + - https + ports: + - 22657/tcp + - 22656/tcp + - 1317/tcp + + - name: trusted + sources: + - 23.111.78.179/32 + - 23.111.78.182/32 diff --git a/host_vars/lx-daemon/nginx.yml b/host_vars/lx-daemon/nginx.yml new file mode 100644 index 0000000..0557caf --- /dev/null +++ b/host_vars/lx-daemon/nginx.yml @@ -0,0 +1,21 @@ +--- +nginx_packages_intall: false +nginx_server_name_hash: 64 +nginx_proxy_read_timeout: 1200 +nginx_proxy_send_timeout: 1200 +nginx_proxy_connection_timeout: 75 + +nginx_sites: + - name: lx-console + url: lx-console.audubon.app + upstream: http://localhost:8080 + template: basic-proxy + ssl: true + + - name: lx-daemon + url: lx-daemon.audubon.app + upstream: http://localhost:9473 + configs: + - rewrite ^/deployer(/.*)? https://webapp-deployer.pwa.audubon.app permanent + template: websocket-proxy + ssl: true diff --git a/hosts b/hosts new file mode 100644 index 0000000..174990d --- /dev/null +++ b/hosts @@ -0,0 +1,11 @@ +[all] +lx-daemon ansible_host= +lx-cad-cluster-control ansible_host= +lx-cad-cluster-worker ansible_host= + +[so] +lx-daemon + +[lx_cad] +lx-cad-cluster-control k8s_node_type=bootstrap +lx-cad-cluster-worker k8s_node_type=agent k8s_pod_limit=1024 k8s_external_ip= diff --git a/roles/requirements.yml b/roles/requirements.yml new file mode 100644 index 0000000..7803c4e --- /dev/null +++ b/roles/requirements.yml @@ -0,0 +1,20 @@ +--- +- name: firewalld + scm: git + src: https://github.com/srwadleigh/ansible-role-firewalld + version: main + +- name: nginx + scm: git + src: https://github.com/srwadleigh/ansible-role-nginx + version: main + +- name: so + scm: git + src: https://github.com/srwadleigh/ansible-role-so + version: main + +- name: k8s + scm: git + src: https://github.com/srwadleigh/ansible-role-k8s + version: main diff --git a/site.yml b/site.yml new file mode 100644 index 0000000..f30d9a4 --- /dev/null +++ b/site.yml @@ -0,0 +1,25 @@ +--- +- name: Setup hosts + hosts: all + become: true + roles: + - role: firewalld + - role: nginx + +- name: Setup stack orchestrator + hosts: so + become: true + roles: + - role: so + tags: + - never + - so + +- name: Setup k8s clusters + hosts: k8s + become: true + roles: + - role: k8s + tags: + - never + - k8s