From be1b7029f0af0dde61d27758ff8c8aece802edcd Mon Sep 17 00:00:00 2001 From: Arthur Zapparoli <2992+arthurgeek@users.noreply.github.com> Date: Thu, 15 Jun 2023 00:20:06 +0200 Subject: [PATCH] feat: Move from Cloudflare's API Key to API Token (#789) Co-authored-by: Arthur Zapparoli --- .config.sample.env | 9 +++-- README.md | 37 ++++++++++++++++--- configure | 10 ++--- .../cert-manager/issuers/issuers.yaml | 14 +++---- .../external-dns/app/helmrelease.yaml | 9 +---- tmpl/kubernetes/cert-manager-secret.sops.yaml | 2 +- tmpl/kubernetes/cluster-secrets.sops.yaml | 2 +- tmpl/kubernetes/external-dns-secret.sops.yaml | 3 +- 8 files changed, 51 insertions(+), 35 deletions(-) diff --git a/.config.sample.env b/.config.sample.env index 6e213136..9c19c41d 100644 --- a/.config.sample.env +++ b/.config.sample.env @@ -29,13 +29,14 @@ export BOOTSTRAP_AGE_PUBLIC_KEY="" # e.g. America/New_York export BOOTSTRAP_TIMEZONE="Etc/UTC" +# The email you want to be associated with the ACME account +export BOOTSTRAP_ACME_EMAIL="" + # Choose one of your cloudflare domains # e.g. onedr0p.com export BOOTSTRAP_CLOUDFLARE_DOMAIN="" -# The email you use to sign into Cloudflare with -export BOOTSTRAP_CLOUDFLARE_EMAIL="" -# Your global Cloudflare API Key (not API token) -export BOOTSTRAP_CLOUDFLARE_APIKEY="" +# Your global Cloudflare API Token (not API Key) +export BOOTSTRAP_CLOUDFLARE_APITOKEN="" # Create a cloudflare tunnel to automatically ingress into your cluster # https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/local/ diff --git a/README.md b/README.md index cff08746..eb03232f 100644 --- a/README.md +++ b/README.md @@ -144,17 +144,27 @@ It is advisable to install [pre-commit](https://pre-commit.com/) and the pre-com 4. Fill out the Age public key in the appropriate variable in configuration section below, **note** the public key should start with `age`... -### ☁️ Cloudflare API Key +### ☁️ Cloudflare API Token -In order to use `cert-manager` with the Cloudflare DNS challenge you will need to create a API key. +In order to use `cert-manager` with the Cloudflare DNS challenge you will need to create a API Token. -1. Head over to Cloudflare and create a API key by going [here](https://dash.cloudflare.com/profile/api-tokens). +1. Head over to Cloudflare and create a API Token by going [here](https://dash.cloudflare.com/profile/api-tokens). -2. Under the `API Keys` section, create a global API Key. +2. Under the `API Tokens` section, click the blue "Create Token" button. -3. Use the API Key in the appropriate variable in configuration section below. +3. Click the "Use template" blue button for the `Edit zone DNS` template. -📍 You may wish to update this later on to a Cloudflare **API Token** which can be scoped to certain resources. I do not recommend using a Cloudflare **API Key**, however for the purposes of this template it is easier getting started without having to define which scopes and resources are needed. For more information see the [Cloudflare docs on API Keys and Tokens](https://developers.cloudflare.com/api/). +4. Give your token a name like `home-k8s-cluster` + +5. Under `Permissions`, click `+ Add More` and add each permission below: + + ```text + Zone - DNS - Edit # should be there already if using the template from the previous step + Account - Cloudflare Tunnel - Read + ``` + +Feel free to limit the permissions to a specific account and zone resources. +6. Use the API Token in the appropriate variable in configuration section below. ### ☁️ Cloudflare Tunnel @@ -462,11 +472,14 @@ The benefits of a public repository include: Expand to read guide on adding Flux SSH authentication 1. Generate new SSH key: + ```sh ssh-keygen -t ecdsa -b 521 -C "github-deploy-key" -f ./kubernetes/bootstrap/github-deploy.key -q -P "" ``` + 2. Paste public key in the deploy keys section of your repository settings 3. Create sops secret in `./kubernetes/bootstrap/github-deploy-key.sops.yaml` with the contents of: + ```yaml apiVersion: v1 kind: Secret @@ -485,15 +498,21 @@ The benefits of a public repository include: github.com ecdsa-sha2-nistp256 ... github.com ssh-rsa ... ``` + 4. Encrypt secret: + ```sh sops --encrypt --in-place ./kubernetes/bootstrap/github-deploy-key.sops.yaml ``` + 5. Apply secret to cluster: + ```sh sops --decrypt ./kubernetes/bootstrap/github-deploy-key.sops.yaml | kubectl apply -f - ``` + 6. Update `./kubernetes/flux/config/cluster.yaml`: + ```yaml apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: GitRepository @@ -509,16 +528,22 @@ The benefits of a public repository include: secretRef: name: github-deploy-key ``` + 7. Commit and push changes 8. Force flux to reconcile your changes + ```sh task cluster:reconcile ``` + 9. Verify git repository is now using SSH: + ```sh task cluster:gitrepositories ``` + 10. Optionally set your repository to Private in your repository settings. + ### 💨 Kubernetes Dashboard diff --git a/configure b/configure index 4ab293e6..f70c2ab0 100755 --- a/configure +++ b/configure @@ -294,13 +294,12 @@ verify_master_count() { verify_cloudflare() { local errors= local account_zone= - _has_envar "BOOTSTRAP_CLOUDFLARE_APIKEY" "true" + _has_envar "BOOTSTRAP_CLOUDFLARE_APITOKEN" "true" _has_envar "BOOTSTRAP_CLOUDFLARE_DOMAIN" "true" - _has_envar "BOOTSTRAP_CLOUDFLARE_EMAIL" "true" + _has_envar "BOOTSTRAP_ACME_EMAIL" "true" # Try to retrieve zone information from Cloudflare's API account_zone=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=${BOOTSTRAP_CLOUDFLARE_DOMAIN}&status=active" \ - -H "X-Auth-Email: ${BOOTSTRAP_CLOUDFLARE_EMAIL}" \ - -H "X-Auth-Key: ${BOOTSTRAP_CLOUDFLARE_APIKEY}" \ + -H "Authorization: Bearer ${BOOTSTRAP_CLOUDFLARE_APITOKEN}" \ -H "Content-Type: application/json" ) if [[ "$(echo "${account_zone}" | jq ".success")" == "true" ]]; then @@ -316,8 +315,7 @@ verify_cloudflare() { _has_envar "BOOTSTRAP_CLOUDFLARE_TUNNEL_ID" "true" # Try to retrieve the Cloudflare Tunnel information from Cloudflare's API cloudflare_tunnel=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${BOOTSTRAP_CLOUDFLARE_ACCOUNT_TAG}/cfd_tunnel/${BOOTSTRAP_CLOUDFLARE_TUNNEL_ID}" \ - -H "X-Auth-Email: ${BOOTSTRAP_CLOUDFLARE_EMAIL}" \ - -H "X-Auth-Key: ${BOOTSTRAP_CLOUDFLARE_APIKEY}" \ + -H "Authorization: Bearer ${BOOTSTRAP_CLOUDFLARE_APITOKEN}" \ -H "Content-Type: application/json" ) if [[ "$(echo "${cloudflare_tunnel}" | jq ".success")" == "true" ]]; then diff --git a/kubernetes/apps/cert-manager/cert-manager/issuers/issuers.yaml b/kubernetes/apps/cert-manager/cert-manager/issuers/issuers.yaml index 473fb7b4..1cf7148a 100644 --- a/kubernetes/apps/cert-manager/cert-manager/issuers/issuers.yaml +++ b/kubernetes/apps/cert-manager/cert-manager/issuers/issuers.yaml @@ -5,16 +5,15 @@ metadata: spec: acme: server: https://acme-v02.api.letsencrypt.org/directory - email: "${SECRET_CLOUDFLARE_EMAIL}" + email: "${SECRET_ACME_EMAIL}" privateKeySecretRef: name: letsencrypt-production solvers: - dns01: cloudflare: - email: "${SECRET_CLOUDFLARE_EMAIL}" - apiKeySecretRef: + apiTokenSecretRef: name: cert-manager-secret - key: api-key + key: api-token selector: dnsZones: - "${SECRET_DOMAIN}" @@ -26,16 +25,15 @@ metadata: spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory - email: "${SECRET_CLOUDFLARE_EMAIL}" + email: "${SECRET_ACME_EMAIL}" privateKeySecretRef: name: letsencrypt-staging solvers: - dns01: cloudflare: - email: "${SECRET_CLOUDFLARE_EMAIL}" - apiKeySecretRef: + apiTokenSecretRef: name: cert-manager-secret - key: api-key + key: api-token selector: dnsZones: - "${SECRET_DOMAIN}" diff --git a/kubernetes/apps/networking/external-dns/app/helmrelease.yaml b/kubernetes/apps/networking/external-dns/app/helmrelease.yaml index 417f23b9..40c40876 100644 --- a/kubernetes/apps/networking/external-dns/app/helmrelease.yaml +++ b/kubernetes/apps/networking/external-dns/app/helmrelease.yaml @@ -29,16 +29,11 @@ spec: fullnameOverride: *app provider: cloudflare env: - - name: CF_API_EMAIL + - name: CF_API_TOKEN valueFrom: secretKeyRef: name: external-dns-secret - key: email - - name: CF_API_KEY - valueFrom: - secretKeyRef: - name: external-dns-secret - key: api-key + key: api-token extraArgs: - --annotation-filter=external-dns.alpha.kubernetes.io/target - --cloudflare-proxied diff --git a/tmpl/kubernetes/cert-manager-secret.sops.yaml b/tmpl/kubernetes/cert-manager-secret.sops.yaml index 49000027..e36d65bc 100644 --- a/tmpl/kubernetes/cert-manager-secret.sops.yaml +++ b/tmpl/kubernetes/cert-manager-secret.sops.yaml @@ -5,4 +5,4 @@ metadata: name: cert-manager-secret namespace: cert-manager stringData: - api-key: "${BOOTSTRAP_CLOUDFLARE_APIKEY}" + api-token: "${BOOTSTRAP_CLOUDFLARE_APITOKEN}" diff --git a/tmpl/kubernetes/cluster-secrets.sops.yaml b/tmpl/kubernetes/cluster-secrets.sops.yaml index 20671779..db3baf55 100644 --- a/tmpl/kubernetes/cluster-secrets.sops.yaml +++ b/tmpl/kubernetes/cluster-secrets.sops.yaml @@ -6,5 +6,5 @@ metadata: namespace: flux-system stringData: SECRET_DOMAIN: "${BOOTSTRAP_CLOUDFLARE_DOMAIN}" - SECRET_CLOUDFLARE_EMAIL: "${BOOTSTRAP_CLOUDFLARE_EMAIL}" + SECRET_ACME_EMAIL: "${BOOTSTRAP_ACME_EMAIL}" SECRET_CLOUDFLARE_TUNNEL_ID: "${BOOTSTRAP_CLOUDFLARE_TUNNEL_ID}" diff --git a/tmpl/kubernetes/external-dns-secret.sops.yaml b/tmpl/kubernetes/external-dns-secret.sops.yaml index 5047e45c..fd509728 100644 --- a/tmpl/kubernetes/external-dns-secret.sops.yaml +++ b/tmpl/kubernetes/external-dns-secret.sops.yaml @@ -5,5 +5,4 @@ metadata: name: external-dns-secret namespace: networking stringData: - email: "${BOOTSTRAP_CLOUDFLARE_EMAIL}" - api-key: "${BOOTSTRAP_CLOUDFLARE_APIKEY}" + api-token: "${BOOTSTRAP_CLOUDFLARE_APITOKEN}"