From d8b441ec03ae32f718713f148169098ed9a756a4 Mon Sep 17 00:00:00 2001 From: Diogo Silva Date: Sat, 10 Aug 2024 22:35:57 +0100 Subject: [PATCH] ci: add updated CI --- .github/workflows/ci.yml | 49 ++++++++++ .github/workflows/deploy.yml | 148 ------------------------------ README.md | 14 +++ ci-patches/argocd-rbac-patch.yaml | 14 +++ 4 files changed, 77 insertions(+), 148 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/deploy.yml create mode 100644 ci-patches/argocd-rbac-patch.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..06e90db --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: "CI" +on: + push: + branches: + - main + pull_request: + workflow_dispatch: +jobs: + default: + runs-on: ubuntu-latest + env: + AUTH_KEY: ${{ secrets.HEADSCALE_PREAUTH_KEY }} + HEADSCALE_API_URL: "https://dsilva-headscale-vpn.fly.dev" + TAILSCALE_UPGRADE: "1" + steps: + # Connect to private network with tailscale + - name: Install tailscale + run: curl -fsSL https://tailscale.com/install.sh | sh + + - name: Start Tailscale + run: sudo tailscale up --auth-key $AUTH_KEY --login-server $HEADSCALE_API_URL --accept-routes + + - name: Tailscale status + run: tailscale status + + - name: Checkout code + uses: actions/checkout@v3 + + - uses: azure/setup-kubectl@v4 + id: kubectl-install + with: + version: 'v1.30.1' + + - name: Setup kubeconfig + run: | + mkdir -p ~/.kube + echo "${{ secrets.KUBECONFIG }}" > ~/.kube/config + + - name: Setup ArgoCD OIDC and RBAC + run: | + echo "Setting up ArgoCD OIDC and RBAC" + kubectl -n argocd patch secret argocd-secret -p '{ + "stringData": { + "oidc.keycloak.clientSecret": "'$ARGOCD_OIDC_CLIENT_SECRET'" + } + }' + kubectl -n argocd patch cm argocd-cm --type merge --patch "$(cat ./ci-patches/argocd-rbac-patch.yaml)" + env: + ARGOCD_OIDC_CLIENT_SECRET: ${{ secrets.ARGOCD_OIDC_CLIENT_SECRET }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 2f79834..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,148 +0,0 @@ -name: "Deploy" -on: - push: - branches: - - main - pull_request: - workflow_dispatch: -jobs: - # Generate a tailscale vpn auth key with oauth2 client - generate-tailscale-authkey: - runs-on: ubuntu-latest - env: - CLIENT_ID: ${{ secrets.TAILSCALE_OAUTH_CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.TAILSCALE_OAUTH_CLIENT_SECRET }} - steps: - - name: Generate Tailscale Auth Key - id: generate-key - run: | - # Generate access token with Oauth2 client - ACCESS_TOKEN=$(curl -s -d "client_id=${CLIENT_ID}" -d "client_secret=${CLIENT_SECRET}" "https://api.tailscale.com/api/v2/oauth/token" | jq -r '.access_token') - # Then create a one-off auth key via API with the access token we previously created - AUTH_KEY=$(curl -s --location 'https://api.tailscale.com/api/v2/tailnet/-/keys' \ - --header "Authorization: Bearer ${ACCESS_TOKEN}" \ - --header "Content-Type: application/json" \ - --data '{ - "capabilities": { - "devices": { - "create": { - "ephemeral": true, - "tags": ["tag:cicd"] - } - } - }, - "expirySeconds": 120}' \ - | jq -r ".key") - - # Save the auth key as step output - echo "AUTH_KEY=$AUTH_KEY" >> $GITHUB_OUTPUT - outputs: - # Export step output as job output - AUTH_KEY: ${{ steps.generate-key.outputs.AUTH_KEY }} - - # Deploy infrastructure - deploy: - name: "Deploy with Terraform" - needs: generate-tailscale-authkey - runs-on: ubuntu-latest - permissions: - pull-requests: write - env: - # Get auth key from previous job - TAILSCALE_AUTH_KEY: ${{ needs.generate-tailscale-authkey.outputs.AUTH_KEY }} - TAILSCALE_UPGRADE: "1" - # Configuration for S3 backend (automatically read by Terraform) - AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }} - AWS_REGION: "eu-south-2" - steps: - # Connect to private network with tailscale - - name: Install tailscale - run: curl -fsSL https://tailscale.com/install.sh | sh - - name: Start Tailscale - run: sudo tailscale up --auth-key $TAILSCALE_AUTH_KEY --accept-routes - - name: Tailscale status - run: tailscale status - # Checkout repository code - - name: Checkout - uses: actions/checkout@v3 - # Install terraform - - - name: Setup Terraform - uses: hashicorp/setup-terraform@v1 - with: - terraform_wrapper: false - - - name: Terraform Format - id: fmt - run: terraform -chdir=terraform fmt -check - - - name: Terraform Init - id: init - run: terraform -chdir=terraform init - - - name: Terraform Validate - id: validate - run: terraform -chdir=terraform validate -no-color - - - name: Terraform Plan - id: plan - if: github.event_name == 'pull_request' - run: terraform -chdir=terraform plan -no-color -input=false - continue-on-error: true - - - name: Update Pull Request - uses: actions/github-script@v6 - if: github.event_name == 'pull_request' - env: - PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\` - #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` - #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` - #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\` - -
Show Plan - - \`\`\`\n - ${process.env.PLAN} - \`\`\` - -
- - *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`; - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: output - }) - - # If terraform previously failed abort pipeline - - name: Terraform Plan Status - if: steps.plan.outcome == 'failure' - run: exit 1 - - # Deploy with terraform on pushes to main branch - - name: Terraform Apply - if: github.ref == 'refs/heads/main' && github.event_name == 'push' - id: terraform-apply # needed to get output value in next step - run: make apply - env: - TF_VAR_proxmox_api_url: ${{ secrets.PROXMOX_API_URL }} - TF_VAR_proxmox_api_token_id: ${{ secrets.PROXMOX_API_TOKEN_ID }} - TF_VAR_proxmox_api_token_secret: ${{ secrets.PROXMOX_API_TOKEN_SECRET }} - TF_VAR_ciuser: ${{ secrets.CI_USER }} - TF_VAR_ssh_keys: ${{ secrets.SSH_KEY }} - TF_VAR_ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }} - # Cloudflare variables - TF_VAR_cloudflare_zone_id: ${{ secrets.CLOUDFLARE_ZONE_ID }} - TF_VAR_cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - TF_VAR_cloudflare_email: ${{ secrets.CLOUDFLARE_EMAIL }} - TF_VAR_cloudflare_token: ${{ secrets.CLOUDFLARE_TOKEN }} - TF_VAR_cloudflare_dns_zone: "dsilva.dev" - TF_VAR_cloudflare_tunnel_name: "k3s" - TF_VAR_coinmarketcap_api_key: ${{ secrets.COINMARKETCAP_API_KEY }} diff --git a/README.md b/README.md index e057159..ff5015c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,20 @@ # 👋 Welcome to k3s.dsilva.dev :test_tube: +# Steps: + +```shell +export PRIVATEKEY="private.key" +export PUBLICKEY="public.crt" +export NAMESPACE="sealed-secrets" +export SECRETNAME="keys" + +openssl req -x509 -days 358000 -nodes -newkey rsa:4096 -keyout "$PRIVATEKEY" -out "$PUBLICKEY" -subj "/CN=sealed-secret/O=sealed-secret" + +kubectl create namespace "$NAMESPACE" +kubectl -n "$NAMESPACE" create secret tls "$SECRETNAME" --cert="$PUBLICKEY" --key="$PRIVATEKEY" +kubectl -n "$NAMESPACE" label secret "$SECRETNAME" sealedsecrets.bitnami.com/sealed-secrets-key=active +``` ### This open-source repository showcases a fully automated homelab k3s cluster on Proxmox, managed with Terraform and ArgoCD :rocket: diff --git a/ci-patches/argocd-rbac-patch.yaml b/ci-patches/argocd-rbac-patch.yaml new file mode 100644 index 0000000..4349039 --- /dev/null +++ b/ci-patches/argocd-rbac-patch.yaml @@ -0,0 +1,14 @@ +# Kubeclt patch to sync groups from keycloak +# with ArgoCD roles +# To add a new group, add a new line to the +# policy.csv file using the format +# g, , role: +# Where is the name of the group +# in keycloak and is the name of +# the role in ArgoCD +# Apply this patch with: +# kubectl -n argocd patch configmap argocd-rbac-cm --patch "$(cat ci-patches/argocd-rbac-patch.yaml)" +data: + policy.csv: | + g, ReadOnly, role:readonly + g, ArgoAdmin, role:admin