diff --git a/.gitlab/.gitlab-ci.yml b/.gitlab/.gitlab-ci.yml index d3507e7..4c7a36a 100644 --- a/.gitlab/.gitlab-ci.yml +++ b/.gitlab/.gitlab-ci.yml @@ -24,3 +24,11 @@ build_dev: rules: - changes: - "dev/terraform/*.tf" + +build_prd: + stage: triggers + trigger: + include: prd/.gitlab/.gitlab-ci.yml + rules: + - changes: + - "prd/terraform/*.tf" diff --git a/dev/metallb-system/templates/config.yaml b/dev/metallb-system/templates/config.yaml index f08a885..5fb85fe 100644 --- a/dev/metallb-system/templates/config.yaml +++ b/dev/metallb-system/templates/config.yaml @@ -4,7 +4,7 @@ metadata: name: cheap spec: addresses: - - 192.168.98.130-192.168.98.140 + - 192.168.10.130-192.168.10.140 --- apiVersion: metallb.io/v1beta1 kind: L2Advertisement diff --git a/prd/.gitlab/.gitlab-ci.yml b/prd/.gitlab/.gitlab-ci.yml new file mode 100644 index 0000000..99ddf7b --- /dev/null +++ b/prd/.gitlab/.gitlab-ci.yml @@ -0,0 +1,95 @@ +stages: + - plan + - apply + - destroy + +variables: + WORKDIR: $CI_PROJECT_DIR/prd/terraform + GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/prd + +image: + name: registry.durp.info/opentofu/opentofu:latest + entrypoint: [""] + +.tf-init: + before_script: + - cd $WORKDIR + - tofu init + -reconfigure + -backend-config="address=${GITLAB_TF_ADDRESS}" + -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" + -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" + -backend-config="username=gitlab-ci-token" + -backend-config="password=${CI_JOB_TOKEN}" + -backend-config="lock_method=POST" + -backend-config="unlock_method=DELETE" + -backend-config="retry_wait_min=5" + +format: + stage: .pre + allow_failure: false + script: + - cd $WORKDIR + - tofu fmt -diff -check -write=false + rules: + - changes: + - "prd/terraform/*.tf" + +validate: + stage: .pre + allow_failure: false + extends: .tf-init + script: + - tofu validate + rules: + - changes: + - "prd/terraform/*.tf" + +plan-prd-infrastructure: + stage: plan + variables: + PLAN: plan.tfplan + JSON_PLAN_FILE: tfplan.json + ENVIRONMENT_NAME: prd + allow_failure: false + extends: .tf-init + script: + - apk add --update curl jq + - alias convert_report="jq -r '([.resource_changes[].change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'" + - tofu plan -out=$PLAN $ARGUMENTS + - tofu show --json $PLAN | jq -r '([.resource_changes[].change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > $JSON_PLAN_FILE + artifacts: + reports: + terraform: $WORKDIR/$JSON_PLAN_FILE + needs: ["validate","format"] + rules: + - changes: + - "prd/terraform/*.tf" + +apply-prd-infrastructure: + stage: apply + variables: + ENVIRONMENT_NAME: prd + allow_failure: false + extends: .tf-init + script: + - tofu apply -auto-approve $ARGUMENTS + rules: + - changes: + - "prd/terraform/*.tf" + when: manual + needs: ["plan-prd-infrastructure"] + +destroy-prd-infrastructure: + stage: destroy + variables: + ENVIRONMENT_NAME: prd + allow_failure: false + extends: .tf-init + script: + - tofu destroy -auto-approve $ARGUMENTS + rules: + - changes: + - "prd/terraform/*.tf" + when: manual + needs: ["plan-prd-infrastructure"] diff --git a/prd/cert-manager/Chart.yaml b/prd/cert-manager/Chart.yaml new file mode 100644 index 0000000..ecf60fa --- /dev/null +++ b/prd/cert-manager/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: cert-manager +description: A Helm chart for Kubernetes +type: application +version: 0.0.1 +appVersion: 0.0.1 + +dependencies: +- name: cert-manager + repository: https://charts.jetstack.io + version: v1.16.3 diff --git a/prd/cert-manager/templates/issuer.yaml b/prd/cert-manager/templates/issuer.yaml new file mode 100644 index 0000000..cf61c83 --- /dev/null +++ b/prd/cert-manager/templates/issuer.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: issuer +secrets: + - name: issuer-token-lmzpj + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: issuer-token-lmzpj + annotations: + kubernetes.io/service-account.name: issuer +type: kubernetes.io/service-account-token diff --git a/prd/cert-manager/templates/letsencrypt.yaml b/prd/cert-manager/templates/letsencrypt.yaml new file mode 100644 index 0000000..56b8374 --- /dev/null +++ b/prd/cert-manager/templates/letsencrypt.yaml @@ -0,0 +1,35 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-production +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-production + solvers: + - dns01: + cloudflare: + email: developerdurp@durp.info + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: cloudflare-api-token-secret + +--- + +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: vault-issuer +spec: + vault: + server: https://vault.infra.durp.info + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVzekNDQTV1Z0F3SUJBZ0lVWkV6enhxRXVZaUtIa0wxZGYrQ2IyMk5SUkpNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF4TUpaSFZ5Y0M1cGJtWnZNQjRYRFRJMU1ERXlNekl5TXpRME1sb1hEVE0xTURFeQpNVEV4TVRVMU5Wb3dJREVlTUJ3R0ExVUVBeE1WZG1GMWJIUXVhVzVtY21FdVpIVnljQzVwYm1adk1JSUJJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQWtaTTB1ZTRiTWNtbUFUcytrR1lTcFIyaExVenEKc2NHSXdDdHFtYUtDTWJkMXhobWdqbklSM3p2U1JwdExSMkdWR3ZjMXRpNnFieTBqWFl2Y3FieGtIdmF5MDB6VwoyellOK00ybTRsWHB1V3pnMXQ2TkVvTzZYR0FzR2oydjB2Y1ZrdFBQVTl1ajByR1VWR1dXZnN2am9YcVFGZzVJCmpkeHN4SzlTdk12dzJYdEUzRmdLeHB6Q3l3OTRJbklIbGNQd0ZUTyszWmRLU3RabE1iVURJa21zekxCcldGY3IKWE9zUERmTHhxTXkwQ2svL0xLSXQ4ZGpoMzI1NEZIQjFHRzUra0krSlNXMW8rdFVjTDJOeW12SUlOd20vMmFjUwoxdVRtK2o5VzdpRVhhdjBwSk5tbSsvZHpTc2tjM1kwZnRNMGgySENYZ2l0QklhRVpuVVZuZU5IT0x3SURBUUFCCm80SUI3ekNDQWVzd0RnWURWUjBQQVFIL0JBUURBZ0VHTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME8KQkJZRUZDYVEycTdqN0x5QkdFVEVaNXFhSkFkbElTS0NNQjhHQTFVZEl3UVlNQmFBRk8xakN5R2twRk8rUWlSMgpkZkJNV1ZZZVdyUTJNSUgwQmdnckJnRUZCUWNCQVFTQjV6Q0I1REF6QmdnckJnRUZCUWN3QVlZbmFIUjBjSE02Ckx5OHhPVEl1TVRZNExqSXdMakkxTXpvNE1qQXhMM1l4TDNCcmFTOXZZM053TUQwR0NDc0dBUVVGQnpBQmhqRm8KZEhSd2N6b3ZMM0p2YjNRdGRtRjFiSFF1YVc1MFpYSnVZV3d1WkhWeWNDNXBibVp2TDNZeEwzQnJhUzl2WTNOdwpNREVHQ0NzR0FRVUZCekFDaGlWb2RIUndjem92THpFNU1pNHhOamd1TWpBdU1qVXpPamd5TURFdmRqRXZjR3RwCkwyTmhNRHNHQ0NzR0FRVUZCekFDaGk5b2RIUndjem92TDNKdmIzUXRkbUYxYkhRdWFXNTBaWEp1WVd3dVpIVnkKY0M1cGJtWnZMM1l4TDNCcmFTOWpZVEFnQmdOVkhSRUVHVEFYZ2hWMllYVnNkQzVwYm1aeVlTNWtkWEp3TG1sdQpabTh3YndZRFZSMGZCR2d3WmpBc29DcWdLSVltYUhSMGNITTZMeTh4T1RJdU1UWTRMakl3TGpJMU16bzRNakF4CkwzWXhMM0JyYVM5amNtd3dOcUEwb0RLR01HaDBkSEJ6T2k4dmNtOXZkQzEyWVhWc2RDNXBiblJsY201aGJDNWsKZFhKd0xtbHVabTh2ZGpFdmNHdHBMMk55YkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQXVKK2xwbFkvK0E1TAo1THprbGpiS0RUeTNVNlBMdjFMdHhxVkNPRkdpSlhCblhNanRWVzA3YkJFVWFkekZSTlc4R0hRM3c1UXpPRzZrCi92RS9UcnJKaG83bDA1Si91YytCVXJQU05qZWZMbVFWNmhuNGpyUDg2UFIwdnpSZmJTcUtLQklJRDlNNyt6aTYKR0Z2SGxWa1NIc1F5TVFwN0pPb2F4OUtWelcyWStPSWd3N0xndzJ0UDEyMldDdDJTSUYwUWVub1pIc29XMGd1agp0elRKUm1KRGpuNlhlSjdMM0ZQa2YzN0g2dWIwSmczekJHcjZlb3JFRmZZWk5ONUNYZXpqcU1GQnBSZHE0VUlvCjFNM0E3bzN1eVpGY0ZzcC92R0RjTUJrd2FDc0JWOWlkdS9Id2t2R2FUVU5JMjg1aWxCT1JQRDBiTVpuQUNxLzkKK1EvY2RzTzVsZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtekNDQTRPZ0F3SUJBZ0lVUXdDQXM4MnNnU3VpYVZiakFOSFNjTzJEU2ZBd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF4TUpaSFZ5Y0M1cGJtWnZNQjRYRFRJMU1ERXlNekV4TWpFeU5Wb1hEVE0xTURFeQpNVEV4TVRVMU5Wb3dGREVTTUJBR0ExVUVBeE1KWkhWeWNDNXBibVp2TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCkFBT0NBUThBTUlJQkNnS0NBUUVBbjlmakdScXFGc3FndXo1Nlg2Y1had0VNdEQ5d0Vsd1NGQ2I0RmM4WVR6bEgKNGZWMTNRd1hLRVNMRS9RKzdidzR5NEZKUThCaUdOYnh4YlFPT2dXaGZHR2xReUZhMWxmaEp0WUxmcVJONUMyLwpTN25yMFl4REI5ZHVjNE9BRXhWTDZQcjQvS29jK3ZEWlkwM2w3Unp3bkYyQU9NOURqRlRBU3cwMVRwaENRalJrClUrdXBpTjJUVWhVUGVqVi9nTVIrelhNNnBuOThVQktHMWROdWJTMEh6QU13QUVYQVBtMTQxTkR5V1VDUFQ5KzMKNlAwM0thOG1VVHgzWDQ5T0N0dkpFR0VRYnRsblRGUWFPU2tQMXlMVytYUk1IdzNzUWFWMlBXWHU1ZkluYkVwWgorU3V6bWdMT1h0bVFObUhMYXY5cTFxZVRWa3BCR1BXdmZoMlZoMUpKaFFJREFRQUJvNElCNHpDQ0FkOHdEZ1lEClZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGSmFQMTdmMVp3MFYKNTVLczlVZjBVU1ZXbDBCUE1COEdBMVVkSXdRWU1CYUFGTzFqQ3lHa3BGTytRaVIyZGZCTVdWWWVXclEyTUlIMApCZ2dyQmdFRkJRY0JBUVNCNXpDQjVEQXpCZ2dyQmdFRkJRY3dBWVluYUhSMGNITTZMeTh4T1RJdU1UWTRMakl3CkxqSTFNem80TWpBeEwzWXhMM0JyYVM5dlkzTndNRDBHQ0NzR0FRVUZCekFCaGpGb2RIUndjem92TDNKdmIzUXQKZG1GMWJIUXVhVzUwWlhKdVlXd3VaSFZ5Y0M1cGJtWnZMM1l4TDNCcmFTOXZZM053TURFR0NDc0dBUVVGQnpBQwpoaVZvZEhSd2N6b3ZMekU1TWk0eE5qZ3VNakF1TWpVek9qZ3lNREV2ZGpFdmNHdHBMMk5oTURzR0NDc0dBUVVGCkJ6QUNoaTlvZEhSd2N6b3ZMM0p2YjNRdGRtRjFiSFF1YVc1MFpYSnVZV3d1WkhWeWNDNXBibVp2TDNZeEwzQnIKYVM5allUQVVCZ05WSFJFRURUQUxnZ2xrZFhKd0xtbHVabTh3YndZRFZSMGZCR2d3WmpBc29DcWdLSVltYUhSMApjSE02THk4eE9USXVNVFk0TGpJd0xqSTFNem80TWpBeEwzWXhMM0JyYVM5amNtd3dOcUEwb0RLR01HaDBkSEJ6Ck9pOHZjbTl2ZEMxMllYVnNkQzVwYm5SbGNtNWhiQzVrZFhKd0xtbHVabTh2ZGpFdmNHdHBMMk55YkRBTkJna3EKaGtpRzl3MEJBUXNGQUFPQ0FRRUFpcUFaNHpOSUVrQ1djdnBEUnEwVnlKdWs1OXNWdEpyNVg0RnNjSFExNzluRQpRYmJ2TWUrRUJERlM2WFFtbDFFbGo4amlQYS9ENU85T2M2SWlzbm01K3dlWkt3QXB6L2xRK1hWa1dMQ29FcGxCClpaOWZjV1ZDYk1MdDB4bHQ4cW41ei9tWUtmYkNUN1pDcURPK3ByUVp0K0FESmNRYmlrbmZyb0FBcUViTkt4d04KWTl1VXlPV05GM1N4SkVjaDR3MmR0WCtJRVZteGVabmhNeThPdVAwU1FLbDhhVzQwdWdpRzBaRDV5VEJCZk9EOQp6c3JHU1UvaVNhdG4wYjdiZXZCaGFMOTZoejEvck5SMWNMKzQvYWxiWDJocnI4UnYzL1NCMkRMdE5RbFFXMGxzCkFmaFhBcVA1ekwrWXRnZjFPZi9wVmRnbmh4cllVWTdSS0NTR1k1SGFndz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMekNDQWhlZ0F3SUJBZ0lVTkhkdk96YW0ySFBWZHdYcE1IVXk0d2w4WlJZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF4TUpaSFZ5Y0M1cGJtWnZNQjRYRFRJMU1ERXlNekV4TVRVeU5Wb1hEVE0xTURFeQpNVEV4TVRVMU5Wb3dGREVTTUJBR0ExVUVBeE1KWkhWeWNDNXBibVp2TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCkFBT0NBUThBTUlJQkNnS0NBUUVBOFhEVFZFdFJJMytrNHl1dnFWcWZJaUxSUUpjWGJtaGZWdEFlWWsrNWo5T3gKcDF3OVlIZG5QTHFMRnJEMVB6YWRqcVllQXAvZndsRUZmczZscXdvVFM4Uzl2aGFGcWNnQjU3blZNYjc3ZFRCYgovMDhYSFhPVTZGUFJqZEZLbTVRTXBTN3RuMVhhY1BNeS9vMGJLcVJSRVFlaXVGREdWUnl1RjVQVWd2V2MxZHZKCmwyN0p2dmdZa3RnamZwTlM0RGxDeGc0bEdYVDVhYnZhS2YyaG5yNjVlZ2FJby95UldOOXdudkF6UmlZN29jaTcKR0Exb0t6ODdZYzF0ZkwyZ2N5bnJ3Y2NPT0NGL2VVS2VzSlIxSTZHWE5rTi9hMWZjcitMZDlaOU5oSEJ0Tyt2RQpOOERzWlkra0c3REUzTTRCQ0NURlV6bGxjWUhqYVc0SGFGOXZaVytQWXdJREFRQUJvM2t3ZHpBT0JnTlZIUThCCkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVTdXTUxJYVNrVTc1Q0pIWjEKOEV4WlZoNWF0RFl3SHdZRFZSMGpCQmd3Rm9BVTdXTUxJYVNrVTc1Q0pIWjE4RXhaVmg1YXREWXdGQVlEVlIwUgpCQTB3QzRJSlpIVnljQzVwYm1adk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQVMvcVVJLzFZdjA3eFVUSzVrCnI5M2tDN0dTUHBtcGtYSXNmakNoQWw5M3NlYk4xNDNmdTcwTlVQNzRqakNjMFdrYjhoUm9mR2cxMEUrLzI0cjEKQUkwS3NMaHpLemZJQVN4VVZRQW44UlRwdExydWFhUExib1NBNE1VWjhJQjV5OFZ5OEUzL0t0RDBnRDgwajY0WQpybTlYR0hBMEhUSkhiUFVUYi9SdXgyZzBFN1d0aXlXU1dIOG1xemJlZ1U4SXJrTTNlVlQ0K3lsQkU3WWtmV0RECmR3NDRzQjcxdGZtREtweldnNlhRNllNaDBZZm55RzFmWUNqOUxodWVjTlk5VXVvNmNqRGFBdmt6TWV3V3dxRHgKUTJFa2FzOThEaTZpdENQOHZFVCtnQkRqZUNjK1hSNkh4NnZ6V214bFpod0R1eEVLTDFhMi9EYWJVeEp5TU56dgo1NUZuCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + path: pki/sign/issue-homelab-certs + auth: + kubernetes: + mountPath: /v1/auth/dmz-cluster + role: issuer + secretRef: + name: issuer-token-lmzpj + key: token diff --git a/prd/cert-manager/templates/secretvault.yaml b/prd/cert-manager/templates/secretvault.yaml new file mode 100644 index 0000000..f15a739 --- /dev/null +++ b/prd/cert-manager/templates/secretvault.yaml @@ -0,0 +1,22 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: cloudflare-api-token-secret +spec: + secretStoreRef: + name: vault + kind: ClusterSecretStore + target: + name: cloudflare-api-token-secret + data: + - secretKey: cloudflare-api-token-secret + remoteRef: + key: kv/cert-manager + property: cloudflare-api-token-secret + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault diff --git a/prd/cert-manager/values.yaml b/prd/cert-manager/values.yaml new file mode 100644 index 0000000..c9cf12f --- /dev/null +++ b/prd/cert-manager/values.yaml @@ -0,0 +1,26 @@ +cert-manager: + crds: + enabled: true + image: + registry: registry.internal.durp.info + repository: jetstack/cert-manager-controller + pullPolicy: Always + replicaCount: 3 + extraArgs: + - --dns01-recursive-nameservers=1.1.1.1:53,1.0.0.1:53 + - --dns01-recursive-nameservers-only + podDnsPolicy: None + podDnsConfig: + nameservers: + - "1.1.1.1" + - "1.0.0.1" + webhook: + image: + registry: registry.internal.durp.info + repository: jetstack/cert-manager-webhook + pullPolicy: Always + cainjector: + image: + registry: registry.internal.durp.info + repository: jetstack/cert-manager-cainjector + pullPolicy: Always diff --git a/prd/external-dns/Chart.yaml b/prd/external-dns/Chart.yaml new file mode 100644 index 0000000..8fb36bc --- /dev/null +++ b/prd/external-dns/Chart.yaml @@ -0,0 +1,12 @@ + +apiVersion: v2 +name: external-dns +description: A Helm chart for Kubernetes +type: application +version: 0.0.1 +appVersion: 0.0.1 + +dependencies: +- name: external-dns + repository: https://charts.bitnami.com/bitnami + version: 8.3.8 diff --git a/prd/external-dns/templates/secrets.yaml b/prd/external-dns/templates/secrets.yaml new file mode 100644 index 0000000..0420a5d --- /dev/null +++ b/prd/external-dns/templates/secrets.yaml @@ -0,0 +1,30 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: external-dns-secret +spec: + secretStoreRef: + name: vault + kind: ClusterSecretStore + target: + name: external-dns + data: + - secretKey: cloudflare_api_email + remoteRef: + key: kv/cloudflare + property: cloudflare_api_email + - secretKey: cloudflare_api_key + remoteRef: + key: kv/cloudflare + property: cloudflare_api_key + - secretKey: cloudflare_api_token + remoteRef: + key: kv/cloudflare + property: cloudflare_api_token + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault diff --git a/prd/external-dns/values.yaml b/prd/external-dns/values.yaml new file mode 100644 index 0000000..2052942 --- /dev/null +++ b/prd/external-dns/values.yaml @@ -0,0 +1,18 @@ +external-dns: + global: + imageRegistry: "registry.durp.info" + + image: + pullPolicy: Always + + txtPrefix: "dmz-" + + sources: + - service + + provider: cloudflare + cloudflare: + secretName : "external-dns" + proxied: false + + policy: sync diff --git a/prd/external-secrets/Chart.yaml b/prd/external-secrets/Chart.yaml new file mode 100644 index 0000000..d89a403 --- /dev/null +++ b/prd/external-secrets/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: external-secrets +description: A Helm chart for Kubernetes +type: application +version: 0.0.1 +appVersion: 0.0.1 + +dependencies: +- name: external-secrets + repository: https://charts.external-secrets.io + version: 0.13.0 diff --git a/prd/external-secrets/templates/ca.yaml b/prd/external-secrets/templates/ca.yaml new file mode 100644 index 0000000..9b2a135 --- /dev/null +++ b/prd/external-secrets/templates/ca.yaml @@ -0,0 +1,81 @@ +apiVersion: v1 +data: + vault.pem: | + -----BEGIN CERTIFICATE----- + MIIEszCCA5ugAwIBAgIUZEzzxqEuYiKHkL1df+Cb22NRRJMwDQYJKoZIhvcNAQEL + BQAwFDESMBAGA1UEAxMJZHVycC5pbmZvMB4XDTI1MDEyMzIyMzQ0MloXDTM1MDEy + MTExMTU1NVowIDEeMBwGA1UEAxMVdmF1bHQuaW5mcmEuZHVycC5pbmZvMIIBIjAN + BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkZM0ue4bMcmmATs+kGYSpR2hLUzq + scGIwCtqmaKCMbd1xhmgjnIR3zvSRptLR2GVGvc1ti6qby0jXYvcqbxkHvay00zW + 2zYN+M2m4lXpuWzg1t6NEoO6XGAsGj2v0vcVktPPU9uj0rGUVGWWfsvjoXqQFg5I + jdxsxK9SvMvw2XtE3FgKxpzCyw94InIHlcPwFTO+3ZdKStZlMbUDIkmszLBrWFcr + XOsPDfLxqMy0Ck//LKIt8djh3254FHB1GG5+kI+JSW1o+tUcL2NymvIINwm/2acS + 1uTm+j9W7iEXav0pJNmm+/dzSskc3Y0ftM0h2HCXgitBIaEZnUVneNHOLwIDAQAB + o4IB7zCCAeswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O + BBYEFCaQ2q7j7LyBGETEZ5qaJAdlISKCMB8GA1UdIwQYMBaAFO1jCyGkpFO+QiR2 + dfBMWVYeWrQ2MIH0BggrBgEFBQcBAQSB5zCB5DAzBggrBgEFBQcwAYYnaHR0cHM6 + Ly8xOTIuMTY4LjIwLjI1Mzo4MjAxL3YxL3BraS9vY3NwMD0GCCsGAQUFBzABhjFo + dHRwczovL3Jvb3QtdmF1bHQuaW50ZXJuYWwuZHVycC5pbmZvL3YxL3BraS9vY3Nw + MDEGCCsGAQUFBzAChiVodHRwczovLzE5Mi4xNjguMjAuMjUzOjgyMDEvdjEvcGtp + L2NhMDsGCCsGAQUFBzAChi9odHRwczovL3Jvb3QtdmF1bHQuaW50ZXJuYWwuZHVy + cC5pbmZvL3YxL3BraS9jYTAgBgNVHREEGTAXghV2YXVsdC5pbmZyYS5kdXJwLmlu + Zm8wbwYDVR0fBGgwZjAsoCqgKIYmaHR0cHM6Ly8xOTIuMTY4LjIwLjI1Mzo4MjAx + L3YxL3BraS9jcmwwNqA0oDKGMGh0dHBzOi8vcm9vdC12YXVsdC5pbnRlcm5hbC5k + dXJwLmluZm8vdjEvcGtpL2NybDANBgkqhkiG9w0BAQsFAAOCAQEAuJ+lplY/+A5L + 5LzkljbKDTy3U6PLv1LtxqVCOFGiJXBnXMjtVW07bBEUadzFRNW8GHQ3w5QzOG6k + /vE/TrrJho7l05J/uc+BUrPSNjefLmQV6hn4jrP86PR0vzRfbSqKKBIID9M7+zi6 + GFvHlVkSHsQyMQp7JOoax9KVzW2Y+OIgw7Lgw2tP122WCt2SIF0QenoZHsoW0guj + tzTJRmJDjn6XeJ7L3FPkf37H6ub0Jg3zBGr6eorEFfYZNN5CXezjqMFBpRdq4UIo + 1M3A7o3uyZFcFsp/vGDcMBkwaCsBV9idu/HwkvGaTUNI285ilBORPD0bMZnACq/9 + +Q/cdsO5lg== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIEmzCCA4OgAwIBAgIUQwCAs82sgSuiaVbjANHScO2DSfAwDQYJKoZIhvcNAQEL + BQAwFDESMBAGA1UEAxMJZHVycC5pbmZvMB4XDTI1MDEyMzExMjEyNVoXDTM1MDEy + MTExMTU1NVowFDESMBAGA1UEAxMJZHVycC5pbmZvMIIBIjANBgkqhkiG9w0BAQEF + AAOCAQ8AMIIBCgKCAQEAn9fjGRqqFsqguz56X6cXZwEMtD9wElwSFCb4Fc8YTzlH + 4fV13QwXKESLE/Q+7bw4y4FJQ8BiGNbxxbQOOgWhfGGlQyFa1lfhJtYLfqRN5C2/ + S7nr0YxDB9duc4OAExVL6Pr4/Koc+vDZY03l7RzwnF2AOM9DjFTASw01TphCQjRk + U+upiN2TUhUPejV/gMR+zXM6pn98UBKG1dNubS0HzAMwAEXAPm141NDyWUCPT9+3 + 6P03Ka8mUTx3X49OCtvJEGEQbtlnTFQaOSkP1yLW+XRMHw3sQaV2PWXu5fInbEpZ + +SuzmgLOXtmQNmHLav9q1qeTVkpBGPWvfh2Vh1JJhQIDAQABo4IB4zCCAd8wDgYD + VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJaP17f1Zw0V + 55Ks9Uf0USVWl0BPMB8GA1UdIwQYMBaAFO1jCyGkpFO+QiR2dfBMWVYeWrQ2MIH0 + BggrBgEFBQcBAQSB5zCB5DAzBggrBgEFBQcwAYYnaHR0cHM6Ly8xOTIuMTY4LjIw + LjI1Mzo4MjAxL3YxL3BraS9vY3NwMD0GCCsGAQUFBzABhjFodHRwczovL3Jvb3Qt + dmF1bHQuaW50ZXJuYWwuZHVycC5pbmZvL3YxL3BraS9vY3NwMDEGCCsGAQUFBzAC + hiVodHRwczovLzE5Mi4xNjguMjAuMjUzOjgyMDEvdjEvcGtpL2NhMDsGCCsGAQUF + BzAChi9odHRwczovL3Jvb3QtdmF1bHQuaW50ZXJuYWwuZHVycC5pbmZvL3YxL3Br + aS9jYTAUBgNVHREEDTALgglkdXJwLmluZm8wbwYDVR0fBGgwZjAsoCqgKIYmaHR0 + cHM6Ly8xOTIuMTY4LjIwLjI1Mzo4MjAxL3YxL3BraS9jcmwwNqA0oDKGMGh0dHBz + Oi8vcm9vdC12YXVsdC5pbnRlcm5hbC5kdXJwLmluZm8vdjEvcGtpL2NybDANBgkq + hkiG9w0BAQsFAAOCAQEAiqAZ4zNIEkCWcvpDRq0VyJuk59sVtJr5X4FscHQ179nE + QbbvMe+EBDFS6XQml1Elj8jiPa/D5O9Oc6Iisnm5+weZKwApz/lQ+XVkWLCoEplB + ZZ9fcWVCbMLt0xlt8qn5z/mYKfbCT7ZCqDO+prQZt+ADJcQbiknfroAAqEbNKxwN + Y9uUyOWNF3SxJEch4w2dtX+IEVmxeZnhMy8OuP0SQKl8aW40ugiG0ZD5yTBBfOD9 + zsrGSU/iSatn0b7bevBhaL96hz1/rNR1cL+4/albX2hrr8Rv3/SB2DLtNQlQW0ls + AfhXAqP5zL+Ytgf1Of/pVdgnhxrYUY7RKCSGY5Hagw== + -----END CERTIFICATE----- + -----BEGIN CERTIFICATE----- + MIIDLzCCAhegAwIBAgIUNHdvOzam2HPVdwXpMHUy4wl8ZRYwDQYJKoZIhvcNAQEL + BQAwFDESMBAGA1UEAxMJZHVycC5pbmZvMB4XDTI1MDEyMzExMTUyNVoXDTM1MDEy + MTExMTU1NVowFDESMBAGA1UEAxMJZHVycC5pbmZvMIIBIjANBgkqhkiG9w0BAQEF + AAOCAQ8AMIIBCgKCAQEA8XDTVEtRI3+k4yuvqVqfIiLRQJcXbmhfVtAeYk+5j9Ox + p1w9YHdnPLqLFrD1PzadjqYeAp/fwlEFfs6lqwoTS8S9vhaFqcgB57nVMb77dTBb + /08XHXOU6FPRjdFKm5QMpS7tn1XacPMy/o0bKqRREQeiuFDGVRyuF5PUgvWc1dvJ + l27JvvgYktgjfpNS4DlCxg4lGXT5abvaKf2hnr65egaIo/yRWN9wnvAzRiY7oci7 + GA1oKz87Yc1tfL2gcynrwccOOCF/eUKesJR1I6GXNkN/a1fcr+Ld9Z9NhHBtO+vE + N8DsZY+kG7DE3M4BCCTFUzllcYHjaW4HaF9vZW+PYwIDAQABo3kwdzAOBgNVHQ8B + Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7WMLIaSkU75CJHZ1 + 8ExZVh5atDYwHwYDVR0jBBgwFoAU7WMLIaSkU75CJHZ18ExZVh5atDYwFAYDVR0R + BA0wC4IJZHVycC5pbmZvMA0GCSqGSIb3DQEBCwUAA4IBAQAS/qUI/1Yv07xUTK5k + r93kC7GSPpmpkXIsfjChAl93sebN143fu70NUP74jjCc0Wkb8hRofGg10E+/24r1 + AI0KsLhzKzfIASxUVQAn8RTptLruaaPLboSA4MUZ8IB5y8Vy8E3/KtD0gD80j64Y + rm9XGHA0HTJHbPUTb/Rux2g0E7WtiyWSWH8mqzbegU8IrkM3eVT4+ylBE7YkfWDD + dw44sB71tfmDKpzWg6XQ6YMh0YfnyG1fYCj9LhuecNY9Uuo6cjDaAvkzMewWwqDx + Q2Ekas98Di6itCP8vET+gBDjeCc+XR6Hx6vzWmxlZhwDuxEKL1a2/DabUxJyMNzv + 55Fn + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + name: ca-pemstore diff --git a/prd/external-secrets/values.yaml b/prd/external-secrets/values.yaml new file mode 100644 index 0000000..304180d --- /dev/null +++ b/prd/external-secrets/values.yaml @@ -0,0 +1,94 @@ +external-secrets: + replicaCount: 3 + revisionHistoryLimit: 1 + leaderElect: true + + installCRDs: true + crds: + createClusterExternalSecret: true + createClusterSecretStore: true + createClusterGenerator: true + createPushSecret: true + conversion: + enabled: false + + image: + repository: registry.durp.info/external-secrets/external-secrets + pullPolicy: Always + + extraVolumes: + - name: ca-pemstore + configMap: + name: ca-pemstore + + extraVolumeMounts: + - name: ca-pemstore + mountPath: /etc/ssl/certs/vault.pem + subPath: vault.pem + readOnly: true + + resources: + requests: + memory: 32Mi + cpu: 10m + limits: + memory: 32Mi + cpu: 10m + + webhook: + create: false + failurePolicy: Ignore + log: + level: debug + image: + repository: registry.durp.info/external-secrets/external-secrets + pullPolicy: Always + + extraVolumes: + - name: ca-pemstore + configMap: + name: ca-pemstore + + extraVolumeMounts: + - name: ca-pemstore + mountPath: /etc/ssl/certs/vault.pem + subPath: vault.pem + readOnly: true + + resources: + requests: + memory: 32Mi + cpu: 10m + limits: + memory: 32Mi + cpu: 10m + + certController: + create: false + revisionHistoryLimit: 1 + log: + level: debug + + image: + repository: registry.durp.info/external-secrets/external-secrets + pullPolicy: Always + tag: "" + + resources: + requests: + memory: 32Mi + cpu: 10m + limits: + memory: 32Mi + cpu: 10m + + extraVolumes: + - name: ca-pemstore + configMap: + name: ca-pemstore + + extraVolumeMounts: + - name: ca-pemstore + mountPath: /etc/ssl/certs/vault.pem + subPath: vault.pem + readOnly: true diff --git a/prd/metallb-system/Chart.yaml b/prd/metallb-system/Chart.yaml new file mode 100644 index 0000000..4fc684f --- /dev/null +++ b/prd/metallb-system/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: metallb-system +description: A Helm chart for Kubernetes +type: application + +version: 0.1.0 +appVersion: "1.16.0" + +dependencies: +- name: metallb + repository: https://metallb.github.io/metallb + version: 0.14.9 diff --git a/prd/metallb-system/templates/config.yaml b/prd/metallb-system/templates/config.yaml new file mode 100644 index 0000000..03314b3 --- /dev/null +++ b/prd/metallb-system/templates/config.yaml @@ -0,0 +1,17 @@ +apiVersion: metallb.io/v1beta1 +kind: IPAddressPool +metadata: + name: cheap +spec: + addresses: + - 192.168.11.130-192.168.11.140 +--- +apiVersion: metallb.io/v1beta1 +kind: L2Advertisement +metadata: + name: pool + namespace: metallb-system +spec: + ipAddressPools: + - cheap + diff --git a/prd/metallb-system/values.yaml b/prd/metallb-system/values.yaml new file mode 100644 index 0000000..e69de29 diff --git a/prd/terraform/k3s.tf b/prd/terraform/k3s.tf new file mode 100644 index 0000000..4d02a21 --- /dev/null +++ b/prd/terraform/k3s.tf @@ -0,0 +1,115 @@ +resource "proxmox_vm_qemu" "k3smaster" { + count = local.k3smaster.count + ciuser = "administrator" + vmid = "${local.vlan}${local.k3smaster.ip[count.index]}" + name = local.k3smaster.name[count.index] + target_node = local.k3smaster.node[count.index] + clone = local.template + tags = local.k3smaster.tags + qemu_os = "l26" + full_clone = true + os_type = "cloud-init" + agent = 1 + cores = local.k3smaster.cores + sockets = 1 + cpu_type = "host" + memory = local.k3smaster.memory + scsihw = "virtio-scsi-pci" + #bootdisk = "scsi0" + boot = "order=virtio0" + onboot = true + sshkeys = local.sshkeys + vga { + type = "serial0" + } + serial { + id = 0 + type = "socket" + } + disks { + ide { + ide2 { + cloudinit { + storage = local.k3smaster.storage + } + } + } + virtio { + virtio0 { + disk { + size = local.k3smaster.drive + format = local.format + storage = local.k3smaster.storage + } + } + } + } + network { + id = 0 + model = "virtio" + bridge = "vmbr0" + tag = local.vlan + } + #Cloud Init Settings + ipconfig0 = "ip=192.168.${local.vlan}.${local.k3smaster.ip[count.index]}/24,gw=192.168.${local.vlan}.1" + searchdomain = "durp.loc" + nameserver = local.dnsserver +} + +resource "proxmox_vm_qemu" "k3sserver" { + count = local.k3sserver.count + ciuser = "administrator" + vmid = "${local.vlan}${local.k3sserver.ip[count.index]}" + name = local.k3sserver.name[count.index] + target_node = local.k3sserver.node[count.index] + clone = local.template + tags = local.k3sserver.tags + qemu_os = "l26" + full_clone = true + os_type = "cloud-init" + agent = 1 + cores = local.k3sserver.cores + sockets = 1 + cpu_type = "host" + memory = local.k3sserver.memory + scsihw = "virtio-scsi-pci" + #bootdisk = "scsi0" + boot = "order=virtio0" + onboot = true + sshkeys = local.sshkeys + vga { + type = "serial0" + } + serial { + id = 0 + type = "socket" + } + disks { + ide { + ide2 { + cloudinit { + storage = local.k3sserver.storage + } + } + } + virtio { + virtio0 { + disk { + size = local.k3sserver.drive + format = local.format + storage = local.k3sserver.storage + } + } + } + } + network { + id = 0 + model = "virtio" + bridge = "vmbr0" + tag = local.vlan + } + #Cloud Init Settings + ipconfig0 = "ip=192.168.${local.vlan}.${local.k3sserver.ip[count.index]}/24,gw=192.168.${local.vlan}.1" + searchdomain = "durp.loc" + nameserver = local.dnsserver +} diff --git a/prd/terraform/main.tf b/prd/terraform/main.tf new file mode 100644 index 0000000..c6c6c8e --- /dev/null +++ b/prd/terraform/main.tf @@ -0,0 +1,48 @@ +terraform { + backend "http" {} + required_providers { + proxmox = { + source = "Telmate/proxmox" + version = "3.0.1-rc6" + } + } +} + +provider "proxmox" { + pm_parallel = 1 + pm_tls_insecure = true + pm_api_url = var.pm_api_url + pm_user = var.pm_user + pm_password = var.pm_password + pm_debug = false +} + +locals { + sshkeys = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDEphzWgwUZnvL6E5luKLt3WO0HK7Kh63arSMoNl5gmjzXyhG1DDW0OKfoIl0T+JZw/ZjQ7iii6tmSLFRk6nuYCldqe5GVcFxvTzX4/xGEioAyG0IiUGKy6s+9xzO8QXF0EtSNPH0nfHNKcCjgwWAzM+Lt6gW0Vqs+aU5ICuDiEchmvYPz+rBaVldJVTG7m3ogKJ2aIF7HU/pCPp5l0E9gMOw7s0ABijuc3KXLEWCYgL39jIST6pFH9ceRLmu8Xy5zXHAkkEEauY/e6ld0hlzLadiUD7zYJMdDcm0oRvenYcUlaUl9gS0569IpfsJsjCejuqOxCKzTHPJDOT0f9TbIqPXkGq3s9oEJGpQW+Z8g41BqRpjBCdBk+yv39bzKxlwlumDwqgx1WP8xxKavAWYNqNRG7sBhoWwtxYEOhKXoLNjBaeDRnO5OY5AQJvONWpuByyz0R/gTh4bOFVD+Y8WWlKbT4zfhnN70XvapRsbZiaGhJBPwByAMGg6XxSbC6xtbyligVGCEjCXbTLkeKq1w0DuItY+FBGO3J2k90OiciTVSeyiVz9J/Y03UB0gHdsMCoVNrj+9QWfrTLDhM7D5YrXUt5nj2LQTcbtf49zoQXWxUhozlg42E/FJU/Yla7y55qWizAEVyP2/Ks/PHrF679k59HNd2IJ/aicA9QnmWtLQ== ansible" + template = "Debian12-Template" + format = "raw" + dnsserver = "192.168.11.1" + vlan = 10 + k3smaster = { + tags = "k3s_prd" + count = 3 + name = ["master01-prd", "master02-prd", "master03-prd"] + cores = 2 + memory = "4096" + drive = 20 + storage = "cache-domains" + node = ["mothership", "overlord", "vanguard"] + ip = ["11", "12", "13"] + } + k3sserver = { + tags = "k3s_prd" + count = 3 + name = ["node01-prd", "node02-prd", "node03-prd"] + cores = 4 + memory = "8192" + drive = 120 + storage = "cache-domains" + node = ["mothership", "overlord", "vanguard"] + ip = ["21", "22", "23"] + } +} diff --git a/prd/terraform/variables.tf b/prd/terraform/variables.tf new file mode 100644 index 0000000..29a1c9d --- /dev/null +++ b/prd/terraform/variables.tf @@ -0,0 +1,14 @@ +variable "pm_api_url" { + description = "API URL to Proxmox provider" + type = string +} + +variable "pm_password" { + description = "Passowrd to Proxmox provider" + type = string +} + +variable "pm_user" { + description = "Username to Proxmox provider" + type = string +} diff --git a/prd/traefik/Chart.yaml b/prd/traefik/Chart.yaml new file mode 100644 index 0000000..30f96ac --- /dev/null +++ b/prd/traefik/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: traefik +description: A Helm chart for Kubernetes +type: application +version: 0.0.1 +appVersion: 0.0.1 + +dependencies: +- name: traefik + repository: https://traefik.github.io/charts + version: 34.0.0 diff --git a/prd/traefik/values.yaml b/prd/traefik/values.yaml new file mode 100644 index 0000000..3d1d660 --- /dev/null +++ b/prd/traefik/values.yaml @@ -0,0 +1,58 @@ +traefik: + image: + # registry: registry.durp.info + # repository: traefik + pullPolicy: Always + + providers: + kubernetesCRD: + allowCrossNamespace: true + allowExternalNameServices: true + allowEmptyServices: false + + deployment: + replicas: 3 + revisionHistoryLimit: 1 + + # volumes: + # - name: traefik-configmap + # mountPath: "/config" + # type: configMap + + ingressRoute: + dashboard: + enabled: true + + additionalArguments: + # - "--providers.file.filename=/config/config.yml" + - "--serversTransport.insecureSkipVerify=true" + - "--log.level=DEBUG" + - --experimental.plugins.jwt.moduleName=github.com/traefik-plugins/traefik-jwt-plugin + - --experimental.plugins.jwt.version=v0.7.0 + + autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Pods + value: 1 + periodSeconds: 60 + + # -- [Resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for `traefik` container. + resources: + requests: + cpu: "100m" + memory: "512Mi" + limits: + memory: "512Mi" diff --git a/prd/vault/Chart.yaml b/prd/vault/Chart.yaml new file mode 100644 index 0000000..e52029e --- /dev/null +++ b/prd/vault/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: vault +description: A Helm chart for Kubernetes +type: application +version: 0.0.1 +appVersion: 0.0.1 + +dependencies: +- name: vault + repository: https://helm.releases.hashicorp.com + version: 0.29.1 + diff --git a/prd/vault/templates/secret-store.yaml b/prd/vault/templates/secret-store.yaml new file mode 100644 index 0000000..0486cfd --- /dev/null +++ b/prd/vault/templates/secret-store.yaml @@ -0,0 +1,23 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ClusterSecretStore +metadata: + name: vault +spec: + provider: + vault: + server: "https://vault.infra.durp.info" + path: "kv" + version: "v2" + auth: + kubernetes: + mountPath: "dmz-cluster" + role: "external-secrets" + serviceAccountRef: + name: "vault" + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault diff --git a/prd/vault/values.yaml b/prd/vault/values.yaml new file mode 100644 index 0000000..877d8fe --- /dev/null +++ b/prd/vault/values.yaml @@ -0,0 +1,13 @@ +vault: + global: + enabled: true + tlsDisable: false + externalVaultAddr: "https://vault.infra.durp.info" + resources: + requests: + memory: 256Mi + cpu: 250m + limits: + memory: 256Mi + cpu: 250m +