├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── docs │ ├── gha.sh │ └── preamble │ ├── gha-docs.yml │ └── terraform-pipeline.yml ├── .gitignore ├── README.md ├── ansible ├── ansible.cfg ├── inventory.yml ├── playbook.yml └── roles │ └── k3s │ └── tasks │ └── main.yml ├── argocd ├── apps │ └── nginx │ │ ├── base │ │ ├── deployment.yaml │ │ ├── kustomization.yaml │ │ └── service.yaml │ │ └── envs │ │ ├── production │ │ └── kustomization.yaml │ │ ├── qa │ │ └── kustomization.yaml │ │ └── staging │ │ └── kustomization.yaml ├── appsets │ ├── kustomization.yaml │ ├── qa-apps-appset.yaml │ ├── qa-appset.yaml │ ├── qa-cnpg-appset.yaml │ └── qa-databases-appset.yaml ├── infrastructure │ ├── cnpg │ │ ├── base │ │ │ ├── cnpg-grafana.yaml │ │ │ ├── cnpg.yaml │ │ │ ├── kustomization.yaml │ │ │ └── namespace.yaml │ │ └── envs │ │ │ ├── prod │ │ │ └── kustomization.yaml │ │ │ ├── qa │ │ │ └── kustomization.yaml │ │ │ └── staging │ │ │ └── kustomization.yaml │ └── databases │ │ └── kubecraft-db │ │ ├── base │ │ ├── cluster.yaml │ │ └── kustomization.yaml │ │ └── envs │ │ ├── production │ │ └── kustomization.yaml │ │ ├── qa │ │ └── kustomization.yaml │ │ └── staging │ │ └── kustomization.yaml └── root-app.yaml ├── docs ├── Getting Started │ ├── index.md │ └── pipeline.md ├── Guidelines │ ├── adding-an-author-profile-to-your-blog.md │ ├── crafting-an-effective-pull-request-summary.md │ └── index.md ├── KubeCraft People │ └── index.md ├── Resources │ ├── index.md │ └── terraform.md ├── Updates │ └── Changelog.md ├── assets │ ├── images │ │ └── kubecraft.png │ ├── pages │ │ └── home.html │ └── stylesheets │ │ └── extra.css ├── blog │ ├── .authors.yml │ └── index.md ├── index.md └── terraform-pipeline.md ├── index.html ├── mkdocs.yml ├── requirements.txt └── terraform ├── .terraform.lock.hcl ├── locals.tf ├── main.tf ├── providers.tf └── ssh.tf /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/python 2 | 3 | COPY ./requirements.txt /tmp/requirements.txt 4 | 5 | RUN pip install -r /tmp/requirements.txt 6 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "context": "..", 4 | "dockerfile": "Dockerfile" 5 | }, 6 | "features": { 7 | "ghcr.io/devcontainers-contrib/features/neovim-homebrew:1": {} 8 | }, 9 | "onCreateCommand": "sudo chsh -s /usr/bin/zsh $USER", 10 | "settings": { 11 | "terminal.integrated.defaultProfile.linux": "zsh", 12 | "terminal.integrated.profiles.linux": { 13 | "zsh": { 14 | "path": "/usr/bin/zsh" 15 | } 16 | } 17 | }, 18 | "forwardPorts": [ 19 | 8000 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/docs/gha.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mapfile -t gldt < <(git log --format='%cs' --grep=^docs -i | uniq) 4 | GHA_FP=.github/workflows/docs/preamble 5 | TMP_FP=/tmp/Changelog.md 6 | cat $GHA_FP > $TMP_FP 7 | for dt in "${gldt[@]}"; do 8 | echo "## $dt" >> $TMP_FP 9 | docs=$(git log --format='- %s by %an (%h)' --date=short --grep=^docs --since="${dt} 00:00:00" --until="${dt} 23:59:59") 10 | echo -e "$docs" >> $TMP_FP; 11 | done 12 | -------------------------------------------------------------------------------- /.github/workflows/docs/preamble: -------------------------------------------------------------------------------- 1 | --- 2 | title: Updates 3 | hide: 4 | - toc 5 | --- 6 | 7 | Below is a running list of commits with changes to the project documentation. GitHub Actions repopulates this list on every commit to `main`. All documentation-related commits should start with `docs` to be included in the updates. 8 | 9 | --- 10 | -------------------------------------------------------------------------------- /.github/workflows/gha-docs.yml: -------------------------------------------------------------------------------- 1 | name: GHA Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | update-changelog: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | 18 | - name: Get docs commits 19 | id: docs_commits 20 | env: 21 | SCRIPT: '.github/workflows/docs/gha.sh' 22 | TMP_FP: '/tmp/Changelog.md' 23 | FP: 'docs/Updates/Changelog.md' 24 | run: | 25 | ./$SCRIPT 26 | if [ -z $FP ]; then 27 | touch $FP 28 | fi 29 | if ! diff $TMP_FP $FP &>/dev/null; then 30 | mv $TMP_FP $FP 31 | echo "NEW_CL=true" >> $GITHUB_ENV 32 | fi 33 | 34 | - name: New branch 35 | id: create_branch 36 | if: env.NEW_CL == 'true' 37 | env: 38 | FP: 'docs/Updates/Changelog.md' 39 | run: | 40 | BRANCH_NAME="docs-changelog-$(date +'%Y%m%d-%H%M%S')" 41 | git checkout -b $BRANCH_NAME 42 | git config --global user.name "github-actions[bot]" 43 | git config --global user.email "github-actions@github.com" 44 | git add $FP 45 | git commit -m "chore: Update docs Changelog.md" 46 | git push origin $BRANCH_NAME 47 | echo "BN=$BRANCH_NAME" >> $GITHUB_ENV 48 | 49 | - name: Create Pull Request 50 | if: env.NEW_CL == 'true' 51 | env: 52 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 53 | run: | 54 | gh pr create --title "Update Changelog" \ 55 | --body "This PR updates the Changelog.md file with the latest documentation changes from $(date +'%Y%m%d-%H%M%S')." \ 56 | --base main --head ${{ env.BN }} \ 57 | --label "documentation" -------------------------------------------------------------------------------- /.github/workflows/terraform-pipeline.yml: -------------------------------------------------------------------------------- 1 | name: Terraform pipeline 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | paths: 7 | - 'terraform/**' 8 | branches: 9 | - main 10 | 11 | permissions: 12 | id-token: write 13 | contents: read 14 | 15 | env: 16 | ARM_ACCESS_KEY: ${{ secrets.ARM_ACCESS_KEY }} 17 | ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} 18 | ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 19 | ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} 20 | 21 | jobs: 22 | plan: 23 | runs-on: ubuntu-latest 24 | defaults: 25 | run: 26 | working-directory: ./terraform 27 | name: Plan 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | 32 | - name: Azure login 33 | uses: azure/login@v2 34 | with: 35 | client-id: ${{ secrets.AZURE_CLIENT_ID }} 36 | tenant-id: ${{ secrets.AZURE_TENANT_ID }} 37 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 38 | 39 | - name: Setup terraform 40 | uses: hashicorp/setup-terraform@v3 41 | 42 | - name: Terraform format check 43 | continue-on-error: true 44 | id: fmt 45 | run: terraform fmt -check 46 | 47 | - name: Terraform init 48 | id: init 49 | run: terraform init 50 | 51 | - name: Terraform validate 52 | id: validate 53 | run: terraform validate -no-color 54 | 55 | - name: Terraform plan 56 | id: plan 57 | run: terraform plan -no-color -out terraform-plan 58 | 59 | - uses: WcAServices/markdown-template-action@v1 60 | continue-on-error: true 61 | with: 62 | # These will be injected into the below template, in addition to GitHub's standard 63 | # variables. You can perform string operations here as well. 64 | variables: >- 65 | FMT_OUTCOME="${{ steps.fmt.outcome }}" 66 | INIT_OUTCOME="${{ steps.init.outcome }}" 67 | VALIDATE_OUTCOME="${{ steps.validate.outcome }}" 68 | VALIDATE_OUTPUT="${{ steps.validate.outputs.stdout }}" 69 | PLAN_OUTCOME="${{ steps.plan.outcome }}" 70 | PLAN_OUTPUT="${{ steps.plan.outputs.stdout }}" 71 | 72 | template: | 73 | #### Terraform Format and Style 🖌`$FMT_OUTCOME` 74 | 75 | #### Terraform Initialization ⚙️`$INIT_OUTCOME` 76 | 77 | #### Terraform Validation 🤖`$VALIDATE_OUTCOME` 78 | 79 |
80 | Validation Output 81 | 82 | ``` 83 | $VALIDATE_OUTPUT 84 | ``` 85 | 86 |
87 | 88 | #### Terraform Plan 📖`$PLAN_OUTCOME` 89 | 90 |
91 | 92 | Show Plan 93 | 94 | ```terraform 95 | $PLAN_OUTPUT 96 | ``` 97 | 98 |
99 | 100 | *Actor: @$GITHUB_ACTOR, Action: `$GITHUB_EVENT_NAME`* 101 | 102 | - name: Upload artifact 103 | uses: actions/upload-artifact@v4 104 | with: 105 | name: plan 106 | path: ./terraform 107 | 108 | apply: 109 | runs-on: ubuntu-latest 110 | environment: staging 111 | needs: plan 112 | name: Apply 113 | defaults: 114 | run: 115 | working-directory: ./terraform 116 | steps: 117 | - name: Checkout 118 | uses: actions/checkout@v4 119 | 120 | - name: Azure login 121 | uses: azure/login@v2 122 | with: 123 | client-id: ${{ secrets.AZURE_CLIENT_ID }} 124 | tenant-id: ${{ secrets.AZURE_TENANT_ID }} 125 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 126 | 127 | - name: Setup terraform 128 | uses: hashicorp/setup-terraform@v3 129 | 130 | - name: Terraform init 131 | run: terraform init 132 | 133 | - name: Download artifact 134 | uses: actions/download-artifact@v4 135 | with: 136 | name: plan 137 | path: ./terraform 138 | 139 | - name: Terraform apply 140 | run: terraform apply -auto-approve terraform-plan 141 | 142 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Terraform 2 | .terraform/ 3 | *.tfstate 4 | *.tfstate.* 5 | terraform/terraform.tfstate 6 | 7 | # Python 8 | .venv/ 9 | 10 | # Editor 11 | .vscode/ 12 | 13 | # Bak 14 | *.bak 15 | *~ 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project KubeCraft 2 | 3 | This is KubeCraft. The #1 DevOps community on Skool. 4 | 5 | 6 | 7 | This repository is for managing our community project and documentation. 8 | 9 | The documentation is rendered at the following domain: 10 | 11 | 12 | 13 | ## Contributing 14 | 15 | Please use [Conventional Commits](https://www.conventionalcommits.org/) 16 | 17 | ## Dev Container 18 | 19 | We've set up a simple dev container for the project. 20 | 21 | By installing neovim through the neovim-homebrew feature, brew is also available. 22 | 23 | ### Recommended packages 24 | 25 | - Terraform is not available as an official dev container feature 26 | - installing Azure CLI through brew allows automatic zsh completion to be installed 27 | 28 | ```bash 29 | # Terraform 30 | brew tap hashicorp/tap 31 | brew install hashicorp/tap/terraform 32 | 33 | # Azure CLI 34 | brew install azure-cli 35 | ``` 36 | -------------------------------------------------------------------------------- /ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory = inventory.yaml 3 | interpreter_python = /usr/bin/python3 4 | roles_path = roles 5 | -------------------------------------------------------------------------------- /ansible/inventory.yml: -------------------------------------------------------------------------------- 1 | all: 2 | hosts: 3 | localhost: 4 | ansible_connection: local 5 | -------------------------------------------------------------------------------- /ansible/playbook.yml: -------------------------------------------------------------------------------- 1 | - name: Ansible playbook 2 | hosts: localhost 3 | roles: 4 | - k3s 5 | -------------------------------------------------------------------------------- /ansible/roles/k3s/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Check if K3s binary exists 2 | ansible.builtin.stat: 3 | path: /usr/local/bin/k3s 4 | register: k3s_binary_check 5 | 6 | - name: Ensure K3s is installed 7 | when: not k3s_binary_check.stat.exists 8 | block: 9 | - name: Download the K3s installation script 10 | ansible.builtin.get_url: 11 | url: https://get.k3s.io 12 | dest: /tmp/install_k3s.sh 13 | mode: "0755" 14 | 15 | - name: Install K3s 16 | ansible.builtin.shell: /tmp/install_k3s.sh 17 | args: 18 | executable: /bin/bash 19 | become: true 20 | changed_when: false 21 | 22 | - name: Verify K3s installation 23 | ansible.builtin.command: k3s --version 24 | register: k3s_verify 25 | changed_when: false 26 | failed_when: k3s_verify.rc != 0 27 | 28 | - name: Remove the K3s installation script 29 | ansible.builtin.file: 30 | path: /tmp/install_k3s.sh 31 | state: absent 32 | -------------------------------------------------------------------------------- /argocd/apps/nginx/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx 5 | labels: 6 | app: nginx 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: nginx 12 | template: 13 | metadata: 14 | labels: 15 | app: nginx 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: nginx:latest 20 | ports: 21 | - containerPort: 80 22 | -------------------------------------------------------------------------------- /argocd/apps/nginx/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - deployment.yaml 3 | - service.yaml 4 | 5 | namespace: nginx 6 | -------------------------------------------------------------------------------- /argocd/apps/nginx/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | namespace: nginx 6 | labels: 7 | app: nginx 8 | spec: 9 | selector: 10 | app: nginx 11 | ports: 12 | - protocol: TCP 13 | port: 80 14 | targetPort: 80 15 | type: ClusterIP 16 | -------------------------------------------------------------------------------- /argocd/apps/nginx/envs/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../../base 3 | 4 | namespace: nginx-production 5 | -------------------------------------------------------------------------------- /argocd/apps/nginx/envs/qa/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../../base 3 | 4 | namespace: nginx-qa 5 | -------------------------------------------------------------------------------- /argocd/apps/nginx/envs/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../../base 3 | 4 | namespace: nginx-staging 5 | -------------------------------------------------------------------------------- /argocd/appsets/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | # - qa-appset.yaml 6 | # - staging-appset.yaml 7 | # - production.yaml 8 | - qa-apps-appset.yaml 9 | - qa-cnpg-appset.yaml 10 | - qa-databases-appset.yaml 11 | -------------------------------------------------------------------------------- /argocd/appsets/qa-apps-appset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: qa-apps-appset 5 | namespace: argocd 6 | spec: 7 | goTemplate: true 8 | goTemplateOptions: ["missingkey=error"] 9 | generators: 10 | - git: 11 | repoURL: https://github.com/Tim275/kubecraft.git 12 | revision: HEAD 13 | directories: 14 | - path: argocd/apps/*/envs/qa 15 | template: 16 | metadata: 17 | name: "{{index .path.segments 2}}-qa" 18 | annotations: 19 | argocd.argoproj.io/sync-wave: "5" 20 | spec: 21 | project: default 22 | source: 23 | repoURL: https://github.com/Tim275/kubecraft.git 24 | targetRevision: HEAD 25 | path: "{{.path.path}}" 26 | destination: 27 | server: https://kubernetes.default.svc 28 | namespace: "{{index .path.segments 2}}-qa" 29 | syncPolicy: 30 | automated: 31 | prune: true 32 | selfHeal: true 33 | syncOptions: 34 | - CreateNamespace=true 35 | -------------------------------------------------------------------------------- /argocd/appsets/qa-appset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: my-qa-appset 5 | namespace: argocd 6 | spec: 7 | goTemplate: true 8 | goTemplateOptions: ["missingkey=error"] 9 | generators: 10 | - git: 11 | repoURL: https://github.com/Tim275/kubecraft.git 12 | revision: HEAD 13 | directories: 14 | - path: argocd/apps/*/envs/qa 15 | - path: argocd/infrastructure/cnpg/envs/qa 16 | - path: argocd/infrastructure/databases/*/envs/qa 17 | template: 18 | metadata: 19 | name: '{{ if eq (index .path.segments 1) "infrastructure" }}{{ if eq (index .path.segments 2) "cnpg" }}cnpg-qa{{ else if eq (index .path.segments 2) "databases" }}{{ index .path.segments 3 }}-qa{{ end }}{{ else }}{{ index .path.segments 2 }}-qa{{ end }}' 20 | annotations: 21 | argocd.argoproj.io/sync-wave: '{{ if eq (index .path.segments 1) "infrastructure" }}{{ if eq (index .path.segments 2) "cnpg" }}-5{{ else if eq (index .path.segments 2) "databases" }}0{{ end }}{{ else }}5{{ end }}' 22 | spec: 23 | project: default 24 | source: 25 | repoURL: https://github.com/Tim275/kubecraft.git 26 | targetRevision: HEAD 27 | path: "{{ .path.path }}" 28 | destination: 29 | server: https://kubernetes.default.svc 30 | namespace: '{{ if eq (index .path.segments 1) "infrastructure" }}{{ if eq (index .path.segments 2) "cnpg" }}cnpg-system{{ else if eq (index .path.segments 2) "databases" }}default{{ end }}{{ else }}{{ index .path.segments 2 }}-qa{{ end }}' 31 | syncPolicy: 32 | automated: 33 | prune: true 34 | selfHeal: true 35 | syncOptions: 36 | - CreateNamespace=true 37 | - ServerSideApply=true 38 | -------------------------------------------------------------------------------- /argocd/appsets/qa-cnpg-appset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: qa-cnpg-appset 5 | namespace: argocd 6 | spec: 7 | goTemplate: true # Add this to enable template processing 8 | goTemplateOptions: ["missingkey=error"] # Add this for error handling 9 | generators: 10 | - git: 11 | repoURL: https://github.com/Tim275/kubecraft.git 12 | revision: HEAD 13 | directories: 14 | - path: argocd/infrastructure/cnpg/envs/qa 15 | template: 16 | metadata: 17 | name: "cnpg-qa" 18 | annotations: 19 | argocd.argoproj.io/sync-wave: "-5" 20 | spec: 21 | project: default 22 | source: 23 | repoURL: https://github.com/Tim275/kubecraft.git 24 | targetRevision: HEAD 25 | path: "{{ .path.path }}" # Add spaces for proper Go template syntax 26 | destination: 27 | server: https://kubernetes.default.svc 28 | namespace: "cnpg-system" 29 | syncPolicy: 30 | automated: 31 | prune: true 32 | selfHeal: true 33 | syncOptions: 34 | - CreateNamespace=true 35 | - ServerSideApply=true 36 | -------------------------------------------------------------------------------- /argocd/appsets/qa-databases-appset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: qa-databases-appset 5 | namespace: argocd 6 | spec: 7 | goTemplate: true 8 | goTemplateOptions: ["missingkey=error"] 9 | generators: 10 | - git: 11 | repoURL: https://github.com/Tim275/kubecraft.git 12 | revision: HEAD 13 | directories: 14 | - path: argocd/infrastructure/databases/*/envs/qa 15 | template: 16 | metadata: 17 | name: "{{index .path.segments 3}}-qa" 18 | annotations: 19 | argocd.argoproj.io/sync-wave: "0" 20 | spec: 21 | project: default 22 | source: 23 | repoURL: https://github.com/Tim275/kubecraft.git 24 | targetRevision: HEAD 25 | path: "{{.path.path}}" 26 | destination: 27 | server: https://kubernetes.default.svc 28 | namespace: "default" 29 | syncPolicy: 30 | automated: 31 | prune: true 32 | selfHeal: true 33 | syncOptions: 34 | - CreateNamespace=true 35 | - ServerSideApply=true 36 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/base/cnpg-grafana.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cnpg-grafana-dashboards 5 | namespace: argocd 6 | finalizers: 7 | - resources-finalizer.argocd.argoproj.io 8 | annotations: 9 | argocd.argoproj.io/sync-wave: "1" 10 | spec: 11 | project: default 12 | source: 13 | chart: cloudnative-pg-dashboards 14 | repoURL: https://cloudnative-pg.github.io/grafana-dashboards 15 | targetRevision: 0.0.3 16 | helm: 17 | values: | 18 | grafana: 19 | enabled: true 20 | destination: 21 | server: https://kubernetes.default.svc 22 | namespace: monitoring 23 | syncPolicy: 24 | automated: 25 | prune: true 26 | selfHeal: true 27 | syncOptions: 28 | - CreateNamespace=true 29 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/base/cnpg.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cnpg-operator 5 | namespace: argocd 6 | finalizers: 7 | - resources-finalizer.argocd.argoproj.io 8 | annotations: 9 | argocd.argoproj.io/sync-wave: "-1" # Install this before regular apps 10 | spec: 11 | project: default 12 | source: 13 | chart: cloudnative-pg 14 | repoURL: https://cloudnative-pg.github.io/charts 15 | targetRevision: 0.23.0 16 | helm: 17 | values: | 18 | replicaCount: 1 19 | destination: 20 | server: https://kubernetes.default.svc 21 | namespace: cnpg-system 22 | syncPolicy: 23 | automated: 24 | prune: true 25 | selfHeal: true 26 | syncOptions: 27 | - CreateNamespace=true 28 | - ServerSideApply=true # This flag handles large CRDs correctly 29 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - namespace.yaml 6 | - cnpg.yaml 7 | #- cnpg-grafana.yaml 8 | # - cluster.yaml 9 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/base/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: cnpg-system 5 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/envs/prod/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/envs/qa/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | -------------------------------------------------------------------------------- /argocd/infrastructure/cnpg/envs/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | -------------------------------------------------------------------------------- /argocd/infrastructure/databases/kubecraft-db/base/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: postgresql.cnpg.io/v1 2 | kind: Cluster 3 | metadata: 4 | name: kubecraft-database-cluster 5 | namespace: default # Explicitly setting namespace 6 | spec: 7 | description: Postgres database cluster for kubecraft 8 | imageName: ghcr.io/cloudnative-pg/postgresql:16.6-30-bookworm 9 | instances: 3 10 | 11 | inheritedMetadata: 12 | labels: 13 | app: kubecraft-database 14 | 15 | bootstrap: 16 | initdb: 17 | database: app 18 | owner: app 19 | 20 | storage: 21 | size: 1Gi 22 | -------------------------------------------------------------------------------- /argocd/infrastructure/databases/kubecraft-db/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - cluster.yaml 6 | 7 | # Optional: set namespace if desired 8 | namespace: default 9 | -------------------------------------------------------------------------------- /argocd/infrastructure/databases/kubecraft-db/envs/production/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | -------------------------------------------------------------------------------- /argocd/infrastructure/databases/kubecraft-db/envs/qa/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | -------------------------------------------------------------------------------- /argocd/infrastructure/databases/kubecraft-db/envs/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - ../../base 6 | -------------------------------------------------------------------------------- /argocd/root-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: root-argocd-app 5 | namespace: argocd 6 | spec: 7 | project: default 8 | source: 9 | repoURL: https://github.com/Tim275/kubecraft.git 10 | targetRevision: HEAD 11 | path: argocd/appsets 12 | destination: 13 | server: https://kubernetes.default.svc 14 | namespace: argocd 15 | syncPolicy: 16 | automated: 17 | prune: true 18 | selfHeal: true 19 | -------------------------------------------------------------------------------- /docs/Getting Started/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Getting Started 3 | --- 4 | 5 | This is a work on progress :warning: 6 | -------------------------------------------------------------------------------- /docs/Getting Started/pipeline.md: -------------------------------------------------------------------------------- 1 | # Pipeline Mock-up 2 | 3 | Create an infrastructure for home-labs for a very simple web app. 4 | 5 | ## The objective is to gain practice on the following items 6 | 7 | - Version Control Systems - Git, GitHub 8 | - CI/CD Tools - Azure DevOps Pipelines, Tekton and Gitlab CI 9 | - Containerization and Orchestration - Kubernetes 10 | - Container Registries - Docker Hub 11 | - Infrastructure as Code (IaC) - Helm, Terraform 12 | - Monitoring and Logging - Prometheus, Grafana 13 | - Service Mesh - Istio 14 | - GitOps Tools - Flux, Argo CD 15 | 16 | ## Guiding principles 17 | 18 | 1. The above should not exclude porting to cloud providers for the more advanced professionals. 19 | 2. Each part should be as decoupled as possible to allow porting and maintenance but most importantly modularity so that different implementations could allow focussing on specific aspects. An initial version could be on Proxmox but then people could contribute to running it on say VirtualBox or leave this layer entirely and run on Docker Desktop. 20 | 3. In order to manage complexity, we should aim to pin down the baseline project elements listed above should leaving variations individual endeavours or side-projects. 21 | 4. As for the app, some of us are also developers and maybe could provide suggestions as to what could be more suitable but something that would allow to easily make changes to the code and verify the deployment afterwards. A simple web page that allows to change background colour, some text, or some CSS attribute, etc. 22 | -------------------------------------------------------------------------------- /docs/Guidelines/adding-an-author-profile-to-your-blog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Adding an Author Profile to Your Blog 3 | hide: 4 | - toc 5 | tags: 6 | - guideline 7 | - blog 8 | --- 9 | 10 | Did you know we also write blogs? Our team is passionate about creating content that inspires others to learn and grow. If you share this passion, we’d love to have you join us. 11 | 12 | As an author, your hard work deserves recognition. This article will guide you on how to tag yourself as the author of a blog, ensuring you get the credit you deserve. 13 | 14 | ## Step 1 15 | 16 | Open the file located at `docs/blog/.authors.yml`. You will see that we already have a few authors in there. To join the list, create a new entry. 17 | 18 | ```yaml 19 | authors: 20 | HYP3R00T: #Your GitHub Handle 21 | name: Rajesh Kumar Das # Your display name 22 | description: Contributor # Describe yourself 23 | avatar: https://avatars.githubusercontent.com/u/78068806?v=4 # Link to your GitHub avatar 24 | url: https://github.com/HYP3R00T # Link to your GitHub profile 25 | ``` 26 | 27 | _Note: Make sure you indent your entry properly._ 28 | 29 | ## Step 2 30 | 31 | Now, it's time to tag yourself as the author of a blog. In the blog post, within the frontmatter, put your name under `authors`. 32 | 33 | ```yaml 34 | --- 35 | authors: 36 | - HYP3ROOT # Your GitHub Handle 37 | --- 38 | # Post Content 39 | ``` 40 | 41 | To learn more about it, check out [built-in blog plugin](https://squidfunk.github.io/mkdocs-material/plugins/blog/#meta.authors). 42 | -------------------------------------------------------------------------------- /docs/Guidelines/crafting-an-effective-pull-request-summary.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Crafting an Effective Pull Request Summary 3 | hide: 4 | - toc 5 | tags: 6 | - guideline 7 | - pull_request 8 | --- 9 | 10 | An effective pull request summary ensures clarity and context, helping reviewers understand the changes, their purpose, and any potential impacts. It streamlines the review process, facilitates better collaboration, and minimizes back-and-forth questions. 11 | 12 | We have a template for you. 13 | 14 | ```markdown 15 | ## What? 16 | 17 | ## Why? 18 | 19 | ## How? 20 | 21 | ## Testing? 22 | 23 | ## Screenshots (optional) 24 | 25 | ## Anything Else? 26 | ``` 27 | 28 | To learn more, checkout this awesome article: [Writing A Great Pull Request Description](https://www.pullrequest.com/blog/writing-a-great-pull-request-description/) 29 | -------------------------------------------------------------------------------- /docs/Guidelines/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Guidelines 3 | hide: 4 | - toc 5 | --- 6 | 7 | Welcome to our community project! We strive to create an inclusive and welcoming environment where everyone can contribute and learn. To ensure we maintain a high standard of collaboration, organization, and best practices, we've created this section of guidelines. 8 | 9 | This page serves as a hub for our community standards, offering guidance on everything from making notes and documenting our journey, to maintaining consistency and organization in our work. We believe that clear and thorough documentation is key to our collective success, and these guidelines are here to help us achieve that. 10 | 11 | Below, you'll find links to various pages detailing specific guidelines on how to approach different tasks within our project. Let's build something great together! 12 | 13 | ## Here's a list of how-to guides 14 | 15 | - [Adding an Author Profile to Your Blog](/Guidelines/adding-an-author-profile-to-your-blog/) 16 | - [Crafting an Effective Pull Request Summary](/Guidelines/crafting-an-effective-pull-request-summary/) 17 | -------------------------------------------------------------------------------- /docs/KubeCraft People/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: KubeCraft People 3 | hide: 4 | - toc 5 | - navigation 6 | --- 7 | 8 | We are incredibly proud of our dedicated community members who contribute their time, expertise, and passion to our project. This section showcases some of our contributors, along with their handles and the amazing work they do. Each member brings unique skills and experiences, contributing to the vibrant and collaborative spirit of our community. We're grateful for their hard work and dedication, and we invite you to explore their contributions and connect with them. 9 | 10 | 11 |
12 | [Alessandro Vozza](https://vozza.me/) [:simple-github:](https://github.com/ams0) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/alessandrovozza) 13 | 14 | [Alexander Benisch](https://blog.alexanderbenisch.de/) 15 | 16 | [Alfonso Fortunato](https://alfonsofortunato.com) [:simple-github:](https://github.com/MovieMaker93) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/alfonso-fortunato-a37056b9/) 17 | 18 | [James Barrow](https://jamiebarrow.dev/) [:simple-github:](https://github.com/jamiebarrow) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/jamesbarrow1984) 19 | 20 | [James Lazo (jazo)](https://www.jameslazo.com/) [:simple-github:](https://github.com/jameslazo) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/jameslazo) 21 | 22 | [Jan Charamza](https://charamza.substack.com/) 23 | 24 | [Jayanath Amaranayake](https://fewmorewords.com) [:simple-github:](https://github.com/jayanath) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/jayanath/) 25 | 26 | [Jhonatan Magalhães](https://jhonatantechh.substack.com/) [:simple-github:](https://github.com/zuka1337) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/jrmagalhaes/) [:simple-youtube:](https://www.youtube.com/@nerdevops/videos) 27 | 28 | [Jose Torrado](https://torrado.io/) [:simple-github:](https://github.com/JoseTorrado) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/joseenriquetorrado/) 29 | 30 | [Kamil Mrowka](https://kamilmrowka.com) 31 | 32 | [Mischa van den Burg](https://mischavandenburg.substack.com/) [:simple-github:](https://github.com/mischavandenburg/) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/mischavandenburg) [:simple-youtube:](https://www.youtube.com/@mischavandenburg) 33 | 34 | [Pedro Chang](https://www.pedrotchang.dev/) [:simple-github:](https://github.com/PedroTChang) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/pedrotchang) [:simple-youtube:](https://www.youtube.com/@pedrotchang) 35 | 36 | [Rajesh Kumar Das](https://hyperoot.dev/) [:simple-github:](https://github.com/HYP3R00T) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/rajesh-kumar-das/) [:simple-youtube:](https://www.youtube.com/@hyperoot) 37 | 38 | [Rodrigo Miravalles](https://rmiravalles.github.io/) [:simple-github:](https://github.com/rmiravalles) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/rodrigomiravalles/) 39 | 40 | [Rohan Rajguru](https://srjoeraj.github.io/blog/) [:simple-github:](https://github.com/srjoeraj) [:fontawesome-brands-linkedin:](https://www.linkedin.com/in/rrajguru) 41 | 42 |
43 | -------------------------------------------------------------------------------- /docs/Resources/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Resources 3 | --- 4 | 5 | ## Ansible 6 | 7 | - [Documentation](https://docs.ansible.com/ansible/latest/index.html) 8 | 9 | ## Go 10 | 11 | - [Learn Go with Tests](https://quii.gitbook.io/learn-go-with-tests) 12 | 13 | ## [Terraform](/Resources/terraform/) 14 | 15 | - [Documentation](https://developer.hashicorp.com/terraform/docs) 16 | -------------------------------------------------------------------------------- /docs/Resources/terraform.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Terraform 3 | --- 4 | 5 | ## Free 6 | 7 | [Hashicorp Learn: Aws](https://developer.hashicorp.com/terraform/tutorials/aws-get-started) - Hashicorp's official getting started tutorial for AWS 8 | 9 | [Hashicorp Learn: Azure](https://developer.hashicorp.com/terraform/tutorials/azure-get-started) - Hashicorp's official getting started tutorial for Azure 10 | 11 | [Hashicorp Learn: GCP](https://developer.hashicorp.com/terraform/tutorials/gcp-get-started) - Hashicorp's official getting started tutorial for GCP 12 | 13 | [Ned in the Cloud: Terraform Basics](https://www.youtube.com/watch?v=y7ouzxEJUMg&list=PLXb5972EMl4BfKVDMaJH6Pg9SI6q_HqMg) - A great playlist of videos covering the basics of Terraform 14 | 15 | [Awesome-TF](https://github.com/shuaibiyy/awesome-tf) - A curated list of Terraform resources 16 | 17 | ## Paid 18 | 19 | [More than Certified: HashiCorp Terraform](https://courses.morethancertified.com/p/mtc-terraform) - a great course that also covers some fun projects with Docker, k3s, Node-Red IOT, and CICD deployments. 20 | -------------------------------------------------------------------------------- /docs/Updates/Changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Updates 3 | hide: 4 | - toc 5 | --- 6 | 7 | Below is a running list of commits with changes to the project documentation. GitHub Actions repopulates this list on every commit to `main`. All documentation-related commits should start with `docs` to be included in the updates. 8 | 9 | --- 10 | ## 2025-04-01 11 | - docs: GHA docs bot now live on main by jazo (17235e3) 12 | - docs: added to authors and people by jazo (5f95010) 13 | ## 2025-02-13 14 | - Merge pull request #49 from jamiebarrow/docs/add-github-and-linkedin by Mischa (9d08629) 15 | ## 2025-02-12 16 | - docs: updated my links by James Barrow (b8dfbeb) 17 | ## 2025-01-10 18 | - Merge pull request #42 from mischavandenburg/docs/update-pipeline-instructions by Mischa (7dfce3a) 19 | - docs: update pipeline instructions by Mischa van den Burg (736e89c) 20 | ## 2025-01-09 21 | - docs:added pedro chang by seyza (586831c) 22 | ## 2025-01-01 23 | - docs: Rearranged markdown files and restructured the folders. Minor tweaks to themes. by hyperoot (2ac25a7) 24 | - docs: fix: minor theme fix for search box by hyperoot (421f3ef) 25 | - docs: improved the site and enabled the blogs by hyperoot (2b653a9) 26 | ## 2024-12-31 27 | - docs: update terraform pipeline docs by Lucioschenkel (361ff9b) 28 | ## 2024-12-29 29 | - docs: add documentation around terraform pipeline by Lucioschenkel (ab3321c) 30 | ## 2024-12-25 31 | - docs: include package instructions by Mischa van den Burg (60dcf4d) 32 | ## 2024-08-06 33 | - docs: Adds docs on getting started with Terraform by Rod Stewart (2945005) 34 | -------------------------------------------------------------------------------- /docs/assets/images/kubecraft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mischavandenburg/kubecraft/d00b83bc4439b38a56e28d1d2fb6b83e80fdf110/docs/assets/images/kubecraft.png -------------------------------------------------------------------------------- /docs/assets/pages/home.html: -------------------------------------------------------------------------------- 1 | {% extends "main.html" %} {% block styles %} {{ super() }} 2 | 14 | {% endblock %} {% block content %} 15 | 16 |
17 |
18 |
19 |

Welcome to KubeCraft

20 |

21 | Fast-track becoming a (better) DevOps Engineer. Featuring Mentorship 22 | Calls, Courses and a Premium Community. Perfect for any skill level! 23 |

24 | 29 |
30 |
31 |
32 | 33 | {{ page.content }} {% endblock %} -------------------------------------------------------------------------------- /docs/assets/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --fg: #a6adc8; 3 | --fg-light: #bac2de; 4 | --fg-lighter: #cdd6f4; 5 | --fg-lightest: #ffffff; 6 | 7 | --bg: #11111b; 8 | --bg-light: #181825; 9 | --bg-lighter: #1e1e2e; 10 | --bg-lightest: #313244; 11 | 12 | --blue: #89b4fa; 13 | --blue-light: #89b4fa; 14 | --blue-dark: #89b4fa; 15 | --blue-transparent: #89b4fa80; 16 | 17 | --yellow: #f9e2af; 18 | --yellow-transparent: #f9e2af80; 19 | 20 | --red: #f38ba8; 21 | --red-transparent: #f38ba880; 22 | 23 | --green: #a3be8c; 24 | --green-transparent: #a3be8c80; 25 | 26 | --purple: #cba6f7; 27 | --orange: #fab387; 28 | --teal: #94e2d5; 29 | 30 | --md-hue: 240deg; 31 | 32 | --md-primary-fg-color: var(--bg-light); 33 | --md-primary-fg-color--light: var(--bg-lighter); 34 | --md-primary-fg-color--dark: var(--bg); 35 | --md-primary-bg-color: var(--blue); 36 | --md-primary-bg-color--light: var(--blue-light); 37 | --md-accent-fg-color: var(--blue); 38 | --md-accent-fg-color--transparent: var(--blue-transparent); 39 | --md-accent-bg-color: var(--bg-light); 40 | --md-accent-bg-color--light: var(--bg-lighter); 41 | --md-default-fg-color: var(--fg); 42 | --md-default-fg-color--light: var(--fg-light); 43 | --md-default-fg-color--lighter: var(--fg-lighter); 44 | --md-default-fg-color--lightest: var(--fg-lightest); 45 | --md-default-bg-color: var(--bg); 46 | --md-default-bg-color--light: var(--bg-light); 47 | --md-default-bg-color--lighter: var(--bg-lighter); 48 | --md-default-bg-color--lightest: var(--bg-lightest); 49 | --md-code-fg-color: var(--fg-light); 50 | --md-code-bg-color: var(--bg-lighter); 51 | --md-code-hl-color: var(--blue); 52 | --md-code-hl-color--light: var(--blue-transparent); 53 | --md-code-hl-number-color: var(--orange); 54 | --md-code-hl-special-color: var(--red); 55 | --md-code-hl-function-color: var(--purple); 56 | --md-code-hl-constant-color: var(--blue); 57 | --md-code-hl-keyword-color: var(--teal); 58 | --md-code-hl-string-color: var(--green); 59 | --md-code-hl-name-color: var(--fg-light); 60 | --md-code-hl-operator-color: var(--fg-lighter); 61 | --md-code-hl-punctuation-color: var(--fg-lighter); 62 | --md-code-hl-comment-color: var(--blue-transparent); 63 | --md-code-hl-generic-color: var(--fg-lighter); 64 | --md-code-hl-variable-color: var(--fg-lighter); 65 | --md-typeset-color: var(--fg); 66 | --md-typeset-a-color: var(--blue); 67 | --md-typeset-del-color: var(--red-transparent); 68 | --md-typeset-ins-color: var(--green-transparent); 69 | --md-typeset-kbd-color: var(--bg-light); 70 | --md-typeset-kbd-accent-color: var(--blue); 71 | --md-typeset-kbd-border-color: var(--fg-light); 72 | --md-typeset-mark-color: var(--yellow-transparent); 73 | --md-typeset-table-color: var(--fg-lighter); 74 | --md-typeset-table-color--light: var(--fg-lightest); 75 | --md-admonition-fg-color: var(--fg); 76 | --md-admonition-bg-color: var(--bg); 77 | --md-warning-fg-color: var(--yellow); 78 | --md-warning-bg-color: var(--fg-lighter); 79 | --md-footer-fg-color: var(--fg-light); 80 | --md-footer-fg-color--light: var(--fg-lighter); 81 | --md-footer-fg-color--lighter: var(--fg-lightest); 82 | --md-footer-bg-color: var(--bg); 83 | --md-footer-bg-color--dark: var(--bg-light); 84 | --md-shadow-z1: 0 0.2rem 0.5rem #00000020, 0 0 0.05rem #00000040; 85 | --md-shadow-z2: 0 0.2rem 0.5rem #00000040, 0 0 0.05rem #00000080; 86 | --md-shadow-z3: 0 0.2rem 0.5rem #00000080, 0 0 0.05rem #000000b3; 87 | 88 | color-scheme: dark; 89 | } 90 | 91 | [data-md-color-scheme="Dark_Blue"] { 92 | --fg: #eff1f5; 93 | --fg-light: #eff1f5; 94 | --fg-lighter: #e6e9ef; 95 | --fg-lightest: #dce0e8; 96 | 97 | --bg: #11111b; 98 | --bg-light: #181825; 99 | --bg-lighter: #1e1e2e; 100 | --bg-lightest: #313244; 101 | 102 | --blue: #89b4fa; 103 | --blue-light: #89b4fa; 104 | --blue-dark: #89b4fa; 105 | --blue-transparent: #89b4fa80; 106 | 107 | --yellow: #f9e2af; 108 | --yellow-transparent: #f9e2af80; 109 | 110 | --red: #f38ba8; 111 | --red-transparent: #f38ba880; 112 | 113 | --green: #a3be8c; 114 | --green-transparent: #a3be8c80; 115 | 116 | --purple: #cba6f7; 117 | --orange: #fab387; 118 | --teal: #94e2d5; 119 | 120 | --md-hue: 240deg; 121 | 122 | --md-primary-fg-color: var(--bg-light); 123 | --md-primary-fg-color--light: var(--bg-lighter); 124 | --md-primary-fg-color--dark: var(--bg); 125 | --md-primary-bg-color: var(--blue); 126 | --md-primary-bg-color--light: var(--blue-light); 127 | --md-accent-fg-color: var(--blue); 128 | --md-accent-fg-color--transparent: var(--blue-transparent); 129 | --md-accent-bg-color: var(--bg-light); 130 | --md-accent-bg-color--light: var(--bg-lighter); 131 | --md-default-fg-color: var(--fg); 132 | --md-default-fg-color--light: var(--fg-light); 133 | --md-default-fg-color--lighter: var(--fg-lighter); 134 | --md-default-fg-color--lightest: var(--fg-lightest); 135 | --md-default-bg-color: var(--bg); 136 | --md-default-bg-color--light: var(--bg-light); 137 | --md-default-bg-color--lighter: var(--bg-lighter); 138 | --md-default-bg-color--lightest: var(--bg-lightest); 139 | --md-code-fg-color: var(--fg-light); 140 | --md-code-bg-color: var(--bg-lighter); 141 | --md-code-hl-color: var(--blue); 142 | --md-code-hl-color--light: var(--blue-transparent); 143 | --md-code-hl-number-color: var(--orange); 144 | --md-code-hl-special-color: var(--red); 145 | --md-code-hl-function-color: var(--purple); 146 | --md-code-hl-constant-color: var(--blue); 147 | --md-code-hl-keyword-color: var(--teal); 148 | --md-code-hl-string-color: var(--green); 149 | --md-code-hl-name-color: var(--fg-light); 150 | --md-code-hl-operator-color: var(--fg-lighter); 151 | --md-code-hl-punctuation-color: var(--fg-lighter); 152 | --md-code-hl-comment-color: var(--blue-transparent); 153 | --md-code-hl-generic-color: var(--fg-lighter); 154 | --md-code-hl-variable-color: var(--fg-lighter); 155 | --md-typeset-color: var(--fg); 156 | --md-typeset-a-color: var(--blue); 157 | --md-typeset-del-color: var(--red-transparent); 158 | --md-typeset-ins-color: var(--green-transparent); 159 | --md-typeset-kbd-color: var(--bg-light); 160 | --md-typeset-kbd-accent-color: var(--blue); 161 | --md-typeset-kbd-border-color: var(--fg-light); 162 | --md-typeset-mark-color: var(--yellow-transparent); 163 | --md-typeset-table-color: var(--fg-lighter); 164 | --md-typeset-table-color--light: var(--fg-lightest); 165 | --md-admonition-fg-color: var(--fg); 166 | --md-admonition-bg-color: var(--bg); 167 | --md-warning-fg-color: var(--yellow); 168 | --md-warning-bg-color: var(--fg-lighter); 169 | --md-footer-fg-color: var(--fg-light); 170 | --md-footer-fg-color--light: var(--fg-lighter); 171 | --md-footer-fg-color--lighter: var(--fg-lightest); 172 | --md-footer-bg-color: var(--bg); 173 | --md-footer-bg-color--dark: var(--bg-light); 174 | --md-shadow-z1: 0 0.2rem 0.5rem #00000020, 0 0 0.05rem #00000040; 175 | --md-shadow-z2: 0 0.2rem 0.5rem #00000040, 0 0 0.05rem #00000080; 176 | --md-shadow-z3: 0 0.2rem 0.5rem #00000080, 0 0 0.05rem #000000b3; 177 | 178 | color-scheme: dark; 179 | } 180 | 181 | [data-md-color-scheme="Light_Blue"] { 182 | --fg: #313244; 183 | --fg-light: #1e1e2e; 184 | --fg-lighter: #181825; 185 | --fg-lightest: #11111b; 186 | 187 | --bg: #e6e9ef; 188 | --bg-light: #dce0e8; 189 | --bg-lighter: #eff1f5; 190 | --bg-lightest: #ccd0da; 191 | 192 | --blue: #1e66f5; 193 | --blue-light: #1e66f5; 194 | --blue-dark: #1e66f5; 195 | --blue-transparent: #1e66f580; 196 | 197 | --yellow: #df8e1d; 198 | --yellow-transparent: #df8e1d80; 199 | 200 | --red: #d20f39; 201 | --red-transparent: #d20f3980; 202 | 203 | --green: #40a02b; 204 | --green-transparent: #40a02b80; 205 | 206 | --purple: #8839ef; 207 | --orange: #fe640b; 208 | --teal: #179299; 209 | 210 | --md-hue: 240deg; 211 | 212 | --md-primary-fg-color: var(--bg-light); 213 | --md-primary-fg-color--light: var(--bg-lighter); 214 | --md-primary-fg-color--dark: var(--bg); 215 | --md-primary-bg-color: var(--fg-lightest); 216 | --md-primary-bg-color--light: var(--fg-lightest); 217 | --md-accent-fg-color: var(--fg-lightest); 218 | --md-accent-fg-color--transparent: var(--blue-transparent); 219 | --md-accent-bg-color: var(--bg-light); 220 | --md-accent-bg-color--light: var(--bg-lighter); 221 | --md-default-fg-color: var(--fg); 222 | --md-default-fg-color--light: var(--fg-light); 223 | --md-default-fg-color--lighter: var(--fg-lighter); 224 | --md-default-fg-color--lightest: var(--fg-lightest); 225 | --md-default-bg-color: var(--bg); 226 | --md-default-bg-color--light: var(--bg-light); 227 | --md-default-bg-color--lighter: var(--bg-lighter); 228 | --md-default-bg-color--lightest: var(--bg-lightest); 229 | --md-code-fg-color: var(--fg-light); 230 | --md-code-bg-color: var(--bg-lighter); 231 | --md-code-hl-color: var(--blue); 232 | --md-code-hl-color--light: var(--blue-transparent); 233 | --md-code-hl-number-color: var(--orange); 234 | --md-code-hl-special-color: var(--red); 235 | --md-code-hl-function-color: var(--purple); 236 | --md-code-hl-constant-color: var(--blue); 237 | --md-code-hl-keyword-color: var(--teal); 238 | --md-code-hl-string-color: var(--green); 239 | --md-code-hl-name-color: var(--fg-light); 240 | --md-code-hl-operator-color: var(--fg-lighter); 241 | --md-code-hl-punctuation-color: var(--fg-lighter); 242 | --md-code-hl-comment-color: var(--blue-transparent); 243 | --md-code-hl-generic-color: var(--fg-lighter); 244 | --md-code-hl-variable-color: var(--fg-lighter); 245 | --md-typeset-color: var(--fg); 246 | --md-typeset-a-color: var(--blue); 247 | --md-typeset-del-color: var(--red-transparent); 248 | --md-typeset-ins-color: var(--green-transparent); 249 | --md-typeset-kbd-color: var(--bg-light); 250 | --md-typeset-kbd-accent-color: var(--blue); 251 | --md-typeset-kbd-border-color: var(--fg-light); 252 | --md-typeset-mark-color: var(--yellow-transparent); 253 | --md-typeset-table-color: var(--fg-lighter); 254 | --md-typeset-table-color--light: var(--fg-lightest); 255 | --md-admonition-fg-color: var(--fg); 256 | --md-admonition-bg-color: var(--bg); 257 | --md-warning-fg-color: var(--yellow); 258 | --md-warning-bg-color: var(--fg-lighter); 259 | --md-footer-fg-color: var(--fg-light); 260 | --md-footer-fg-color--light: var(--fg-lighter); 261 | --md-footer-fg-color--lighter: var(--fg-lightest); 262 | --md-footer-bg-color: var(--bg); 263 | --md-footer-bg-color--dark: var(--bg-light); 264 | --md-shadow-z1: 0 0.2rem 0.5rem #00000020, 0 0 0.05rem #00000040; 265 | --md-shadow-z2: 0 0.2rem 0.5rem #00000040, 0 0 0.05rem #00000080; 266 | --md-shadow-z3: 0 0.2rem 0.5rem #00000080, 0 0 0.05rem #000000b3; 267 | } 268 | 269 | .md-button { 270 | border-color: var(--fg-lightest) !important; 271 | color: var(--fg-lightest) !important; 272 | } 273 | 274 | .md-button:hover { 275 | border-color: var(--fg) !important; 276 | color: var(--fg) !important; 277 | background-color: var(--bg-lighter) !important; 278 | } 279 | 280 | .md-button--primary { 281 | border-color: var(--blue) !important; 282 | color: var(--bg) !important; 283 | background-color: var(--blue) !important; 284 | } 285 | 286 | .md-search-result__meta { 287 | color: var(--bg-light) !important; 288 | } 289 | 290 | .md-tag { 291 | background-color: var(--bg-lightest) !important; 292 | } 293 | 294 | /* ! Others */ 295 | 296 | .hero-container { 297 | display: flex; 298 | min-height: calc(100dvh - 228px); 299 | } 300 | 301 | .hero { 302 | position: relative; 303 | flex: 1; 304 | display: flex; 305 | align-items: center; 306 | justify-content: center; 307 | background-color: var(--bg-light); 308 | overflow: hidden; 309 | } 310 | 311 | .hero-content { 312 | text-align: center; 313 | max-width: 800px; 314 | padding: 2rem; 315 | z-index: 1; 316 | } 317 | 318 | .hero h1 { 319 | font-size: 3rem; 320 | margin-bottom: 1rem; 321 | color: hsl(var(--fg)); 322 | } 323 | 324 | .hero p { 325 | font-size: 1rem; 326 | margin-bottom: 2rem; 327 | color: hsl(var(--blue)); 328 | } 329 | 330 | .cta-buttons { 331 | display: flex; 332 | justify-content: center; 333 | gap: 1rem; 334 | } 335 | -------------------------------------------------------------------------------- /docs/blog/.authors.yml: -------------------------------------------------------------------------------- 1 | authors: 2 | HYP3R00T: 3 | name: Rajesh Kumar Das 4 | description: Contributor 5 | avatar: https://avatars.githubusercontent.com/u/78068806?v=4 6 | url: https://github.com/HYP3R00T 7 | 8 | jazo: 9 | name: James Lazo 10 | description: Contributor 11 | avatar: https://avatars.githubusercontent.com/u/131928783?v=4 12 | url: https://github.com/jameslazo -------------------------------------------------------------------------------- /docs/blog/index.md: -------------------------------------------------------------------------------- 1 | # Blog -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | template: home.html 3 | hide: 4 | - toc 5 | - navigation 6 | - footer 7 | title: "Home" 8 | --- 9 | -------------------------------------------------------------------------------- /docs/terraform-pipeline.md: -------------------------------------------------------------------------------- 1 | # How to setup and use the terraform pipeline 2 | 3 | ## Intro 4 | 5 | This document explains how to use the workflow located at `.github/workflows/terraform-pipeline.yml`. You might want to use this workflow to provision the [`kubecraft`](https://github.com/mischavandenburg/kubecraft) community project on your own infrastructure on Azure. 6 | 7 | ## Pre-requisites 8 | 9 | To follow along, you will need: 10 | 11 | - A fork of [`mischavandenburg/kubecraft`](https://github.com/mischavandenburg/kubecraft) on your Github account. 12 | - An Azure account with an active subscription. 13 | 14 | ## Azure setup 15 | 16 | Before executing the pipeline on your Github account, we need to configure the remote backend (`azurerm` provider on Azure Blob Storage) and obtain the details for OIDC authentication. 17 | 18 | ### Service Principal and Federated Identity 19 | 20 | Follow these documents in order for a complete walk-through to setup a service principal with a federated identity for OIDC authentication from Github actions: 21 | 22 | - [Create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal) 23 | - [Configure a federated identity](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#github-actions) 24 | 25 | **Note:** You will need to create credentials valid for a `push` to the `main` branch, and for the `staging` environment. 26 | 27 | - Specify an Entity type of Branch and a GitHub branch name of "main". 28 | - Specify an Entity type of Environment and a GitHub environment name of "staging" (this must correspond with the environment name you set in your repo fork) 29 | 30 | When the service principal is created, assign it the "Contributor" role on the subscription that you will be deploying to. 31 | 32 | ### Remote backend configuration 33 | 34 | For the remote backend configuration, we will need to configure a resource group, storage account, and container on Azure Blob Storage. You can use the following script to provision these resources: 35 | 36 | ```bash 37 | #!/bin/bash 38 | 39 | RESOURCE_GROUP_NAME=tfstate 40 | STORAGE_ACCOUNT_NAME=tfstate$RANDOM 41 | CONTAINER_NAME=tfstate 42 | 43 | # Create resource group 44 | az group create --name $RESOURCE_GROUP_NAME --location eastus 45 | 46 | # Create storage account 47 | az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob 48 | 49 | # Create blob container 50 | az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME 51 | 52 | ACCOUNT_KEY=$(az storage account keys list --resource-group tfstate --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv) 53 | ``` 54 | 55 | Now, take note of your `$STORAGE_ACCOUNT_NAME`. You will need to specify its value under the `storage_account_name` property of the `backend` configuration on `terraform/providers`. 56 | 57 | Also, copy your `ACCOUNT_KEY` and store it on Github Actions secrets under a secret named `ARM_ACCESS_KEY`. 58 | 59 | ### Github environment 60 | 61 | The Terraform pipeline leverages environment protection rules to enable manual approvals for the `terraform apply` command. In order to use this workflow, you will need to create a `staging` environment from your repository settings page (on your own fork). You don't need to add any environment protection rules if you don't want to, but if you do, simply check the "require approvals" checkbox and add yourself as a required reviewer. 62 | 63 | ### Push and Test 64 | 65 | Once you've created the secrets on Github Actions for OIDC authentication, adjusted the backend provider configuration to your own Azure storage account, and created the `staging` environment on your repository, commit your changes and push the code to your `main` branch. This will trigger the pipeline automatically. Alternatively, you can navigate to `https://github.com/your-username/kubecraft/actions`, select the Terraform pipeline workflow on the left hand side menu, and use the "Run workflow" button to manually trigger the workflow execution. 66 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mischavandenburg/kubecraft/d00b83bc4439b38a56e28d1d2fb6b83e80fdf110/index.html -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: KubeCraft 2 | repo_url: https://github.com/mischavandenburg/kubecraft 3 | repo_name: KubeCraft 4 | edit_uri: edit/main/docs 5 | site_url: https://docs.kubecraft.community/ 6 | 7 | theme: 8 | name: material 9 | logo: /assets/images/kubecraft.png 10 | favicon: /assets/images/kubecraft.png 11 | icon: 12 | repo: material/github 13 | edit: material/pencil 14 | view: material/eye 15 | annotation: material/plus-circle 16 | font: 17 | text: Inter 18 | code: Fira Code 19 | custom_dir: docs/assets/pages 20 | palette: 21 | - scheme: Dark_Blue # Palette toggle for dark mode 22 | primary: custom 23 | accent: custom 24 | toggle: 25 | icon: material/toggle-switch-off-outline 26 | name: Prepare for Flashbang! 27 | - scheme: Light_Blue # Palette toggle for light mode 28 | primary: custom 29 | accent: custom 30 | toggle: 31 | icon: material/toggle-switch 32 | name: Join the dark side. We have cookies. 33 | 34 | features: 35 | - content.action.edit 36 | - content.action.view 37 | - search.suggest 38 | - search.share 39 | - navigation.instant 40 | - navigation.instant.progress 41 | - navigation.tracking 42 | - navigation.tabs 43 | - navigation.sections 44 | - navigation.path 45 | - navigation.prune 46 | - navigation.indexes 47 | - navigation.top 48 | - content.code.copy 49 | 50 | plugins: 51 | - search 52 | - blog: 53 | blog_dir: blog 54 | post_dir: blog/posts 55 | - glightbox 56 | 57 | markdown_extensions: 58 | - abbr 59 | - admonition 60 | - attr_list 61 | - md_in_html 62 | - pymdownx.emoji: 63 | emoji_index: !!python/name:material.extensions.emoji.twemoji 64 | emoji_generator: !!python/name:material.extensions.emoji.to_svg 65 | - pymdownx.highlight: 66 | anchor_linenums: true 67 | line_spans: __span 68 | pygments_lang_class: true 69 | - pymdownx.inlinehilite 70 | - pymdownx.snippets 71 | - pymdownx.superfences: 72 | custom_fences: 73 | - name: mermaid 74 | class: mermaid 75 | format: !!python/name:pymdownx.superfences.fence_code_format 76 | - pymdownx.caret 77 | - pymdownx.mark 78 | - pymdownx.tilde 79 | - pymdownx.tasklist: 80 | custom_checkbox: true 81 | - toc: 82 | permalink: true 83 | 84 | extra: 85 | social: 86 | - icon: fontawesome/brands/github 87 | link: https://github.com/mischavandenburg/kubecraft 88 | - icon: material/school 89 | link: https://skool.com/kubecraft 90 | 91 | extra_css: 92 | - assets/stylesheets/extra.css 93 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements for core 2 | jinja2~=3.0 3 | markdown~=3.2 4 | pygments~=2.16 5 | pymdown-extensions~=10.2 6 | 7 | # Requirements for plugins 8 | babel~=2.10 9 | colorama~=0.4 10 | paginate~=0.5 11 | regex>=2022.4 12 | requests~=2.26 13 | 14 | # Requirements for mkdocs 15 | mkdocs~=1.6 16 | mkdocs-material 17 | mkdocs-material-extensions~=1.3 18 | mkdocs-glightbox~=0.4.0 -------------------------------------------------------------------------------- /terraform/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/azure/azapi" { 5 | version = "1.15.0" 6 | constraints = "~> 1.5" 7 | hashes = [ 8 | "h1:Y7ruMuPh8UJRTRl4rm+cdpGtmURx2taqiuqfYaH3o48=", 9 | "zh:0627a8bc77254debc25dc0c7b62e055138217c97b03221e593c3c56dc7550671", 10 | "zh:2fe045f07070ef75d0bec4b0595a74c14394daa838ddb964e2fd23cc98c40c34", 11 | "zh:343009f39c957883b2c06145a5954e524c70f93585f943f1ea3d28ef6995d0d0", 12 | "zh:53fe9ab54485aaebc9b91e27a10bce2729a1c95b1399079e631dc6bb9e3f27dc", 13 | "zh:63c407e7dc04d178d4798c17ad489d9cc92f7d1941d7f4a3f560b95908b6107b", 14 | "zh:7d6fc2b432b264f036bb80ab2b2ba67f80a5d98da8a8c322aa097833dad598c9", 15 | "zh:7ec49c0a8799d469eb6e2a1f856693f9862f1b73f5ed70adc1b346e5a4c6458d", 16 | "zh:889704f10319d301d677539d788fc82a7c73608ab78cb93e1280ac2be39e6e00", 17 | "zh:90b4b07405b7cde9ebae3b034cb5bb5dd18484d1b95bd250f905451f1e86ac3f", 18 | "zh:92aa9c241a8cb2a6d81ad47bc007c119f8b818464a960ebaf39008766c361e6b", 19 | "zh:f28fbd0a2c59e239b53067bc1adc691be444876bcb2d4f78d310f549724da6e0", 20 | "zh:ffb15e0ddfa505d0e9b75341570199076ae574887124f398162b1ead9376b25f", 21 | ] 22 | } 23 | 24 | provider "registry.terraform.io/hashicorp/azurerm" { 25 | version = "3.117.0" 26 | constraints = "~> 3.0" 27 | hashes = [ 28 | "h1:Ynfg+Iy7x6K8M6W1AhqXCe3wkoiqIQhROlca7C3KC3w=", 29 | "zh:2e25f47492366821a786762369f0e0921cc9452d64bfd5075f6fdfcf1a9c6d70", 30 | "zh:41eb34f2f7469bf3eb1019dfb0e7fc28256f809824016f4f8b9d691bf473b2ac", 31 | "zh:48bb9c87b3d928da1abc1d3db75453c9725de4674c612daf3800160cc7145d30", 32 | "zh:5d6b0de0bbd78943fcc65c53944ef4496329e247f434c6eab86ed051c5cea67b", 33 | "zh:78c9f6fdb1206a89cf0e6706b4f46178169a93b6c964a4cad8a321058ccbd9b4", 34 | "zh:793b702c352589d4360b580d4a1cf654a7439d2ad6bdb7bfea91de07bc4b0fac", 35 | "zh:7ed687ff0a5509463a592f97431863574fe5cc80a34e395be06766215b8c6285", 36 | "zh:955ba18789bd15592824eb426a8d0f38595bd09fffc6939c1c58933489c1a71e", 37 | "zh:bf5949a55be0714cd9c8815d472eae4baa48ba06d0f6bf2b96775869acda8a54", 38 | "zh:da5d31f635abd2c645ffc76d6176d73f646128e73720cc368247cc424975c127", 39 | "zh:eed5a66d59883c9c56729b0a964a2b60d758ea7489ef3e920a6fbd48518ce5f5", 40 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 41 | ] 42 | } 43 | 44 | provider "registry.terraform.io/hashicorp/random" { 45 | version = "3.6.3" 46 | constraints = "~> 3.0" 47 | hashes = [ 48 | "h1:Fnaec9vA8sZ8BXVlN3Xn9Jz3zghSETIKg7ch8oXhxno=", 49 | "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", 50 | "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", 51 | "zh:4b4c11ccfba7319e901df2dac836b1ae8f12185e37249e8d870ee10bb87a13fe", 52 | "zh:4fa45c44c0de582c2edb8a2e054f55124520c16a39b2dfc0355929063b6395b1", 53 | "zh:588508280501a06259e023b0695f6a18149a3816d259655c424d068982cbdd36", 54 | "zh:737c4d99a87d2a4d1ac0a54a73d2cb62974ccb2edbd234f333abd079a32ebc9e", 55 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 56 | "zh:a357ab512e5ebc6d1fda1382503109766e21bbfdfaa9ccda43d313c122069b30", 57 | "zh:c51bfb15e7d52cc1a2eaec2a903ac2aff15d162c172b1b4c17675190e8147615", 58 | "zh:e0951ee6fa9df90433728b96381fb867e3db98f66f735e0c3e24f8f16903f0ad", 59 | "zh:e3cdcb4e73740621dabd82ee6a37d6cfce7fee2a03d8074df65086760f5cf556", 60 | "zh:eff58323099f1bd9a0bec7cb04f717e7f1b2774c7d612bf7581797e1622613a0", 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /terraform/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | vm = { 3 | name = "kcVM" # azurerm resource name 4 | hostname = "ubuntu-kubecraft" 5 | location = "northeurope" 6 | size = "Standard_B2ms" 7 | admin_username = "kubecraft" 8 | } 9 | key_vault = { 10 | eso_secret_permissions = [ 11 | "Get", 12 | "List" 13 | ] 14 | admin_secret_permissions = [ 15 | "Get", 16 | "List", 17 | "Set", 18 | "Delete", 19 | "Purge", 20 | "Recover" 21 | ] 22 | # Placeholder for the external secrets operator identifier 23 | # eso_object_id = "" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /terraform/main.tf: -------------------------------------------------------------------------------- 1 | # Create Resource Group 2 | resource "azurerm_resource_group" "rg" { 3 | location = local.vm.location 4 | name = "kcUbuntuResourceGroup" 5 | } 6 | 7 | # Create randomized name for key vault, each key vault must have globally unique ID 8 | resource "random_string" "azurerm_key_vault_name" { 9 | length = 13 10 | lower = true 11 | numeric = false 12 | special = false 13 | upper = false 14 | } 15 | 16 | # Hold client identifying information for privilege & access control 17 | data "azurerm_client_config" "current" {} 18 | 19 | # Create key vault 20 | resource "azurerm_key_vault" "vault" { 21 | name = "kcVault-${random_string.azurerm_key_vault_name.result}" 22 | location = azurerm_resource_group.rg.location 23 | resource_group_name = azurerm_resource_group.rg.name 24 | tenant_id = data.azurerm_client_config.current.tenant_id 25 | sku_name = "standard" 26 | soft_delete_retention_days = 7 27 | 28 | # Policies for the external secrets operator 29 | access_policy { 30 | tenant_id = data.azurerm_client_config.current.tenant_id 31 | object_id = data.azurerm_client_config.current.object_id # Remove this line and uncomment the next once ESO id is stored in local 32 | #object_id = local.key_vault.eso_object_id 33 | 34 | secret_permissions = local.key_vault.eso_secret_permissions 35 | } 36 | 37 | # Policies for the 'control panel' applying our Terraform configs 38 | access_policy { 39 | tenant_id = data.azurerm_client_config.current.tenant_id 40 | object_id = data.azurerm_client_config.current.object_id 41 | 42 | secret_permissions = local.key_vault.admin_secret_permissions 43 | } 44 | } 45 | 46 | # Create virtual network 47 | resource "azurerm_virtual_network" "kc_terraform_network" { 48 | name = "kcVnet" 49 | address_space = ["10.0.0.0/16"] 50 | location = azurerm_resource_group.rg.location 51 | resource_group_name = azurerm_resource_group.rg.name 52 | } 53 | 54 | # Create subnet 55 | resource "azurerm_subnet" "kc_terraform_subnet" { 56 | name = "kcSubnet" 57 | resource_group_name = azurerm_resource_group.rg.name 58 | virtual_network_name = azurerm_virtual_network.kc_terraform_network.name 59 | address_prefixes = ["10.0.1.0/24"] 60 | } 61 | 62 | # Create public IPs 63 | resource "azurerm_public_ip" "kc_terraform_public_ip" { 64 | name = "kcPublicIP" 65 | location = azurerm_resource_group.rg.location 66 | resource_group_name = azurerm_resource_group.rg.name 67 | allocation_method = "Dynamic" 68 | } 69 | 70 | # Create Network Security Group and rule 71 | resource "azurerm_network_security_group" "kc_terraform_nsg" { 72 | name = "kcNetworkSecurityGroup" 73 | location = azurerm_resource_group.rg.location 74 | resource_group_name = azurerm_resource_group.rg.name 75 | 76 | security_rule { 77 | name = "SSH" 78 | priority = 1001 79 | direction = "Inbound" 80 | access = "Allow" 81 | protocol = "Tcp" 82 | source_port_range = "*" 83 | destination_port_range = "22" 84 | source_address_prefix = "*" 85 | destination_address_prefix = "*" 86 | } 87 | } 88 | 89 | # Create network interface 90 | resource "azurerm_network_interface" "kc_terraform_nic" { 91 | name = "kcNIC" 92 | location = azurerm_resource_group.rg.location 93 | resource_group_name = azurerm_resource_group.rg.name 94 | 95 | ip_configuration { 96 | name = "kc_nic_configuration" 97 | subnet_id = azurerm_subnet.kc_terraform_subnet.id 98 | private_ip_address_allocation = "Dynamic" 99 | public_ip_address_id = azurerm_public_ip.kc_terraform_public_ip.id 100 | } 101 | } 102 | 103 | # Connect the security group to the network interface 104 | resource "azurerm_network_interface_security_group_association" "kc_terraform_associate" { 105 | network_interface_id = azurerm_network_interface.kc_terraform_nic.id 106 | network_security_group_id = azurerm_network_security_group.kc_terraform_nsg.id 107 | } 108 | 109 | 110 | # Create virtual machine 111 | resource "azurerm_linux_virtual_machine" "kc_terraform_vm" { 112 | name = local.vm.name 113 | location = azurerm_resource_group.rg.location 114 | resource_group_name = azurerm_resource_group.rg.name 115 | network_interface_ids = [azurerm_network_interface.kc_terraform_nic.id] 116 | size = local.vm.size 117 | 118 | os_disk { 119 | name = "kcOsDisk" 120 | caching = "ReadWrite" 121 | storage_account_type = "Standard_LRS" 122 | } 123 | 124 | source_image_reference { 125 | publisher = "Canonical" 126 | offer = "0001-com-ubuntu-server-jammy" 127 | sku = "22_04-lts-gen2" 128 | version = "latest" 129 | } 130 | 131 | computer_name = local.vm.hostname 132 | admin_username = local.vm.admin_username 133 | 134 | admin_ssh_key { 135 | username = local.vm.admin_username 136 | public_key = azapi_resource_action.ssh_public_key_gen.output.publicKey 137 | } 138 | 139 | 140 | admin_ssh_key { 141 | username = local.vm.admin_username 142 | public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7cKlVWUh8/PPsU4pSKjXucEEVDp99JG+EMUy7vf1CTCQoJ54OJ0ShFFPv5ddyDuZ4wVN04UlVXIna25TgDu3F1VpedzT+W7uqB+Evyz+lqtj/m57eLewjzB1w670OgNNE3XjgBG3FRqysyIOq+nG8X2LITVJVprrx7NoOwOZSGu92+8UQ4f0IyMcvvpFgzp+86zaHQ220fasEn8GZ/by2o94BV0Frk98RvnI9/woEQg/zavkQqERqSWl3VLzXNe2kJlcGG613fGZrbtsH2i3UV4yMOxFa1MInzlh4io6FmI9ic3YLJ8L+9BWxN9IdA0mE5N21SpWG9elWp/MmN8vzQvdqKJmKnjZfeLDpNXB9PTKsJ1hkch2ssb/OrfJ5dTIJNQZixL+f1ZumDzfAQXBMaMj8h+oCuiwfyVY9br8JSJeEM7AWVNavmRWdmv/o8XccGn0d2xqEwzBT4GOM/iKR45tI1xMckbfwS8R04OfxVWPB3qsffUwXN4i+wUVox5K1+qSjTcuXiLgdaXDwNaOshzi/iEK9y34StxJ8OxUL8eEuuU2xC49hfP7qqPqWefxqEVBzalpzG5GcokWFF0lmDX5WXj6dF1hKV31p1MglPyVi00RESWbHTAIWc/x5pPUX02tZ9FeFRXSTAAEce0E1WiSu+tbI0+ftUesjizhJIQ== cardno:23_421_713" 143 | } 144 | 145 | 146 | } 147 | -------------------------------------------------------------------------------- /terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">=0.12" 3 | 4 | required_providers { 5 | azapi = { 6 | source = "azure/azapi" 7 | version = "~>1.5" 8 | } 9 | azurerm = { 10 | source = "hashicorp/azurerm" 11 | version = "~>3.0" 12 | } 13 | random = { 14 | source = "hashicorp/random" 15 | version = "~>3.0" 16 | } 17 | } 18 | 19 | backend "azurerm" { 20 | resource_group_name = "tfstate" 21 | # TODO: use your own storage_account_name 22 | storage_account_name = "tfstate7330" 23 | container_name = "tfstate" 24 | key = "terraform.tfstate" 25 | } 26 | } 27 | 28 | provider "azurerm" { 29 | features {} 30 | } 31 | 32 | provider "azapi" { 33 | use_oidc = true 34 | } 35 | 36 | -------------------------------------------------------------------------------- /terraform/ssh.tf: -------------------------------------------------------------------------------- 1 | resource "random_pet" "ssh_key_name" { 2 | prefix = "ssh" 3 | separator = "_" 4 | } 5 | 6 | resource "azapi_resource_action" "ssh_public_key_gen" { 7 | type = "Microsoft.Compute/sshPublicKeys@2022-11-01" 8 | resource_id = azapi_resource.ssh_public_key.id 9 | action = "generateKeyPair" 10 | method = "POST" 11 | 12 | response_export_values = ["publicKey", "privateKey"] 13 | } 14 | 15 | resource "azapi_resource" "ssh_public_key" { 16 | type = "Microsoft.Compute/sshPublicKeys@2022-11-01" 17 | name = random_pet.ssh_key_name.id 18 | location = azurerm_resource_group.rg.location 19 | parent_id = azurerm_resource_group.rg.id 20 | } 21 | 22 | output "key_data" { 23 | value = azapi_resource_action.ssh_public_key_gen.output.publicKey 24 | } 25 | --------------------------------------------------------------------------------