feat(argo): app-of-app argo

Signed-off-by: Tuan-Dat Tran <tuan-dat.tran@tudattr.dev>
This commit is contained in:
Tuan-Dat Tran
2025-07-25 07:58:34 +02:00
parent 0139850ee3
commit 89c51aa45c
28 changed files with 81 additions and 424 deletions

View File

@@ -6,15 +6,5 @@
vars:
is_localhost: "{{ inventory_hostname == '127.0.0.1' }}"
roles:
- role: kubernetes_traefik
when: is_localhost
- role: kubernetes_argocd
when: is_localhost
- role: kubernetes_nfs
when: is_localhost
- role: kubernetes_metallb
when: is_localhost
- role: kubernetes_cert_manager
when: is_localhost
# - role: kubernetes_argo_apps
# when: is_localhost

View File

@@ -2,3 +2,7 @@
argocd_version: stable
argocd_namespace: argocd
argocd_repo: "https://raw.githubusercontent.com/argoproj/argo-cd/refs/tags/{{ argocd_version }}/manifests/ha/install.yaml"
argocd_git_repository: https://github.com/argocd/argocd
argocd_git_username: "user"
argocd_git_pat: "token"

View File

@@ -48,3 +48,23 @@
until: apply_manifests is not failed
retries: 5
delay: 10
- name: Apply ArgoCD repository
kubernetes.core.k8s:
definition: "{{ lookup('ansible.builtin.template', 'repository.yml.j2') | from_yaml }}"
state: present
namespace: "{{ argocd_namespace }}"
register: apply_manifests
until: apply_manifests is not failed
retries: 5
delay: 10
- name: Apply ArgoCD Root Application
kubernetes.core.k8s:
definition: "{{ lookup('ansible.builtin.template', 'root_application.yml.j2') | from_yaml }}"
state: present
namespace: "{{ argocd_namespace }}"
register: apply_manifests
until: apply_manifests is not failed
retries: 5
delay: 10

View File

@@ -1,19 +0,0 @@
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: "{{ item.name }}"
namespace: "{{ argocd_namespace }}"
spec:
project: default
source:
repoURL: "{{ item.repo_url }}"
targetRevision: "{{ item.target_revision }}"
path: "{{ item.path }}"
destination:
server: "{{ item.destination_server }}"
namespace: "{{ item.destination_namespace }}"
syncPolicy:
automated:
prune: true
selfHeal: true

View File

@@ -1,27 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-ingress
namespace: argocd
annotations:
kubernetes.io/ingress.class: traefik
cert-manager.io/cluster-issuer: "{{ argocd_cert_resolver }}"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: {{ argocd_hostname }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80
tls:
- hosts:
- {{ argocd_hostname }}
secretName: k3s-seyshiro-de-tls

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: argocd-repository-https
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
url: {{ argocd_git_repository }}
username: {{ argocd_git_username }}
password: {{ argocd_git_pat }}

View File

@@ -0,0 +1,25 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: homelab-gitops-root
namespace: argocd
labels:
app.kubernetes.io/name: argocd-root
app.kubernetes.io/instance: homelab
app.kubernetes.io/component: gitops-bootstrap
spec:
project: default
source:
repoURL: {{ argocd_git_repository }}
targetRevision: HEAD
path: cluster-apps/
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true

View File

@@ -1,5 +0,0 @@
cert_manager_version: "v1.18.2"
cert_manager_email: "mail@example.com"
cert_manager_manifest: "https://github.com/cert-manager/cert-manager/releases/download/{{ cert_manager_version }}/cert-manager.yaml"
cert_manager_issuer_name: "letsencrypt-prod"
cert_manager_issuer_env: "staging"

View File

@@ -1,77 +0,0 @@
---
- name: Ensure cert-manager namespace exists
kubernetes.core.k8s:
name: cert-manager
api_version: v1
kind: Namespace
state: present
tags:
- cert_manager
- namespace
- name: Create netcup-secret
kubernetes.core.k8s:
namespace: cert-manager
definition: "{{ lookup('ansible.builtin.template', 'netcup.yml.j2') | from_yaml }}"
- name: Add a repository
kubernetes.core.helm_repository:
name: cert-manager-webhook-netcup
repo_url: https://aellwein.github.io/cert-manager-webhook-netcup/charts/
- name: Download cert-manager manifest
ansible.builtin.get_url:
url: "{{ cert_manager_manifest }}"
dest: "/tmp/cert-manager.yaml"
mode: "0644"
validate_certs: true
tags:
- cert_manager
- download
- name: Apply cert-manager core manifests
kubernetes.core.k8s:
src: "/tmp/cert-manager.yaml"
state: present
tags:
- cert_manager
- apply_manifest
- name: Wait for cert-manager deployments to be ready
kubernetes.core.k8s_info:
api_version: apps/v1
kind: Deployment
namespace: cert-manager
name: "{{ item }}"
wait: true
wait_timeout: 300
loop:
- cert-manager
- cert-manager-cainjector
- cert-manager-webhook
tags:
- cert_manager
- wait_ready
- name: Create Let's Encrypt ClusterIssuer
kubernetes.core.k8s:
state: present
definition: "{{ lookup('ansible.builtin.template', 'clusterissuer.yml.j2') | from_yaml }}"
tags:
- cert_manager
- cluster_issuer
- name: Create Let's Encrypt Certificate
kubernetes.core.k8s:
state: present
definition: "{{ lookup('ansible.builtin.template', 'certificate.yml.j2') | from_yaml }}"
tags:
- cert_manager
- certificate
- name: Install NetCup Webhook
kubernetes.core.helm:
name: my-cert-manager-webhook-netcup
chart_ref: cert-manager-webhook-netcup/cert-manager-webhook-netcup
release_namespace: cert-manager
create_namespace: true

View File

@@ -1,16 +0,0 @@
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: k3s-seyshiro-de
namespace: cert-manager
spec:
secretName: k3s-seyshiro-de-tls
issuerRef:
name: {{ cert_manager_issuer_name }}
kind: ClusterIssuer
commonName: "*.k3s.seyshiro.de"
dnsNames:
- "k3s.seyshiro.de"
- "*.k3s.seyshiro.de"

View File

@@ -1,22 +0,0 @@
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: "{{ cert_manager_issuer_name }}"
spec:
acme:
server: "{% if cert_manager_issuer_env == 'production' %}https://acme-v02.api.letsencrypt.org/directory{% else %}https://acme-staging-v02.api.letsencrypt.org/directory{% endif %}"
email: "{{ cert_manager_email }}"
privateKeySecretRef:
name: "{{ cert_manager_issuer_name }}-account-key"
solvers:
- selector:
dnsZones:
- 'k3s.seyshiro.de'
dns01:
webhook:
groupName: com.netcup.webhook
solverName: netcup
config:
secretRef: netcup-secret
secretNamespace: cert-manager

View File

@@ -1,11 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: netcup-secret
type: Opaque
data:
customer-number: {{ netcup_customer_id | b64encode }}
api-key: {{ netcup_api_key |b64encode }}
api-password: {{ netcup_api_password | b64encode }}

View File

@@ -1,4 +0,0 @@
---
metallb_version: v0.15.2
metallb_ip_range: "192.168.178.200-192.168.178.220"
metallb_manifest_url: "https://raw.githubusercontent.com/metallb/metallb/{{ metallb_version }}/config/manifests/metallb-native.yaml"

View File

@@ -1,62 +0,0 @@
---
- name: Ensure metallb-system namespace exists
kubernetes.core.k8s:
name: metallb-system
api_version: v1
kind: Namespace
state: present
tags:
- metallb
- namespace
- name: Download MetalLB manifest
ansible.builtin.get_url:
url: "{{ metallb_manifest_url }}"
dest: "/tmp/metallb.yaml"
mode: "0644"
validate_certs: true
run_once: true
tags:
- metallb
- download
- name: Apply MetalLB core manifests
kubernetes.core.k8s:
src: "/tmp/metallb.yaml"
state: present
namespace: metallb-system
tags:
- metallb
- apply_manifest
- name: Create IPAddressPool for MetalLB
kubernetes.core.k8s:
state: present
namespace: metallb-system
definition: "{{ lookup('ansible.builtin.template', 'ipaddresspool.yml.j2') | from_yaml }}"
tags:
- metallb
- ip_pool
- name: Create L2Advertisement for MetalLB
kubernetes.core.k8s:
state: present
namespace: metallb-system
definition: "{{ lookup('ansible.builtin.template', 'l2advertisement.yml.j2') | from_yaml }}"
tags:
- metallb
- l2_advertisement
- name: Setup DNS on Netcup
community.general.netcup_dns:
api_key: "{{ netcup_api_key }}"
api_password: "{{ netcup_api_password }}"
customer_id: "{{ netcup_customer_id }}"
domain: "{{ domain }}"
name: "{{ service.name }}.k3s"
type: "A"
value: "{{ service.ip }}"
loop: "{{ services }}"
loop_control:
loop_var: service
delegate_to: localhost

View File

@@ -1,9 +0,0 @@
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- "{{ metallb_ip_range }}"

View File

@@ -1,9 +0,0 @@
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default-l2advertisement
namespace: metallb-system
spec:
ipAddressPools:
- default-pool

View File

@@ -1,3 +0,0 @@
---
traefik_dashboard_hostname: "traefik.example.com"
traefik_cert_resolver: "cert_resolver-prod"

View File

@@ -1,12 +0,0 @@
---
# roles/traefik/tasks/main.yml
- name: "Traefik | Enable dashboard"
kubernetes.core.k8s:
template: "helmchartconfig.yaml.j2"
state: present
- name: "Traefik | Create dashboard ingress"
kubernetes.core.k8s:
template: "ingress.yaml.j2"
state: present

View File

@@ -1,17 +0,0 @@
---
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
logs:
access:
enabled: true
ingressRoute:
dashboard:
enabled: true
websecure:
tls:
enabled: true

View File

@@ -1,27 +0,0 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-dashboard
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
cert-manager.io/cluster-issuer: {{ traefik_cert_resolver }}
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: {{ traefik_dashboard_hostname }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: traefik
port:
number: 8080
tls:
- hosts:
- {{ traefik_dashboard_hostname }}
secretName: k3s-seyshiro-de-tls

View File

@@ -1,2 +0,0 @@
argocd_apps_repo_url: ssh://git@git.tudattr.dev/tudattr/argocd.git
argocd_apps_target_revision: main

View File

@@ -1,10 +0,0 @@
- name: Render Argo CD Application YAML to a variable
ansible.builtin.set_fact:
argo_app_manifest: "{{ lookup('ansible.builtin.template', '../templates/argo_app.yaml.j2') }}"
- name: Apply Argo CD Application to Kubernetes using k8s module
kubernetes.core.k8s:
state: present
definition: "{{ argo_app_manifest }}"
register: k8s_apply_result
delegate_to: localhost

View File

@@ -1,5 +0,0 @@
- name: Install Argo Application
ansible.builtin.include_tasks: ./install_argo_app.yml
loop: argo_apps
loop_control:
loop_var: app

View File

@@ -1,24 +0,0 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ app.name }}
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: {{ argocd_apps_repo_url }}
targetRevision: {{ argocd_apps_target_revision | default("HEAD") }}
path: argocd/{{ app.name }}
directory:
recurse: true
destination:
server: https://kubernetes.default.svc
namespace: {{ argocd_apps_target_namespace | default(app.name) }}
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -1,11 +0,0 @@
apiVersion: argoproj.io/v1alpha1
kind: Repository
metadata:
name: {{ argocd_apps_repo_name }}
namespace: argocd
spec:
url: {{ argocd_apps_repo_url }}
type: git
sshPrivateKeySecret:
name: {{ argocd_apps_ssh_private_key_secret_name }}
key: {{ argocd_apps_ssh_private_key_secret_key }}

View File

@@ -1,11 +1,11 @@
$ANSIBLE_VAULT;1.1;AES256
36666266313661333466623135393337366266366135643630663632653035383365393137386636
3462613661396661643733383663386239353238333066650a346334616636376137373866383431
34633734306565333463343230333561633435306564353833613632653531376435363465323237
3462343537373362320a386434633737373535313866393334353239373661393837646637336638
30373364666661373864613136623632333961633134633163333464656131333464323039653432
64383866663935396231356265396334663532376439663335363563326637313730323437363836
65383930646266636261383037613266613238623964633063666266386134313165396336373934
30376433663332316537373466643130656536356439323261643839636537383539646434646665
64376530383832343263303333383435663133363562626638373331663037306462656233316431
6334663737316633613438623762333038663230626133393239
35346663303832663665616362333166613161356534326464386265636330356162633939343834
6362613161663862396664666362363733366436316535610a366533323361646435313831653033
35616333626663346166356663333465356631626131393739333535376539646136326532303734
6663373463326265340a366664656666636430313837666363313562646532303636626365393466
33393965663435613436393363303239633837653962353936663733313437393934383264326638
35323830343530643430643531393366653934653865346165386565633435366432336534623935
66323934373636396135333536353465626134303463666236383737366464626361346265333164
35316636343239333731356232653138656461383963346235346164373563363330366338313532
63646534303130623739386361366131303230373263343636613035653063323534356631356630
6536343535373836333739656362363033323865336665393561

View File

@@ -1,30 +1,9 @@
$ANSIBLE_VAULT;1.1;AES256
36633030306535356337326461613132636632356364633463643133333534626261653034373737
6335626664363163316164396432613935353633333635370a323537346261643962336636386163
64306635366538663736316361663564366636366261336130346563623138323739373230346134
3931373064323063630a656261373630343361613939623163313833663762313833356463356432
64366364363862343466623139346132363361373762363934383731393637653333343036396562
38373336616237323237643730373963663561346430373132313865393662306664306133323163
35633035323339363563323131393130643537323439323138376366386634363566626238613166
32386434333534376166356565646235353533633163643937393337613766616137343463373636
36333637376434383633366166666661373332303266306235376666313562663463613761363637
66653630313934353566663362376633306564313239393433383565653064643632356235386237
32633435336564353130633466373264643765376164663231636232623739326136353439393135
38623461636531653264363732633832343537653833373564366363633032653332346162393137
31333738373965323131623336356136313863616363356130363930653166373034386161343763
31363466643531323865303637333436366636633166666334653934613763393635623563636462
37306337623933313136663665343864643363383839333266303436636435666262336330346337
37663664353066333065666662636663386537366631366465653861633862643733386438653932
30343537343265626430653361396366663565306536343232366138346132343232663831323665
35356233373766333862613235656533623166303033623135373166386564333736393235366662
36623463383135636266396333666134623766616437666538313633316531326565623735396132
64323037636637353633653563333466363432383935346366346631306637323538663062393935
38376363363630653964666637623836666239623638333438383261613038303233363666356266
62613464326265666133323534326339326235376134313530636132303764346331663466323933
30366330663039653662323831393363373236616364366233376232313365383838616331383834
33636165303735376262653137396635373633333735396433633235396264643761336634373637
61386432653565616263613637386431333634346165356637333232393862353234623134363631
34343032313032386136646232633532626137386264653539373361656436663465653535373339
61373539663635623239663137313337373535396535633532363338323930386661366536626533
32623862353233633962313364666537336539643737613734616261313634666533316564323561
3061
38633865326639393736633231333434663333363237386164616637316161613163336663373137
3361323230343236346139666135643663643464366332300a343635663531323362656634356232
36373934336234616661633933396133376161303764326230623132653962366435373661333763
6230393838353739630a333563353138646535353566393438353333643836643938633538396637
62623533376237316530376437383237353631316434376661633334373331343933346262303063
39313735346363396462366431623738396366613636393831353734666465336432633162633233
61646463376238383765356336633333366461333439613737636363393236653439636361373434
30626631316139613730

View File

@@ -15,6 +15,6 @@ metallb_ip_range: "192.168.20.240-192.168.20.250"
kubernetes_nfs_server_host: "{{ nfs_server }}"
kubernetes_nfs_server_path: /media/kubernetes
argocd_apps_repo_url: ssh://git.seyshiro.de:2222/tudattr/ansible.git
argocd_apps_ssh_private_key_secret_name: argocd
argocd_apps_ssh_private_key_secret_key: "{{ vault_kubernetes.argocd_repo_ssh_key }}"
argocd_git_repository: https://git.seyshiro.de/tudattr/homelab-argocd
argocd_git_username: tudattr
argocd_git_pat: "{{ vault_kubernetes.argocd_git_pat }}"