├── .gitignore ├── README.md ├── infra.tf ├── k8s.yaml └── tf-k8s.code-workspace /.gitignore: -------------------------------------------------------------------------------- 1 | .kube/ 2 | 3 | # Local .terraform directories 4 | **/.terraform/* 5 | 6 | # .tfstate files 7 | *.tfstate 8 | *.tfstate.* 9 | 10 | # Crash log files 11 | crash.log 12 | crash.*.log 13 | 14 | # Exclude all .tfvars files, which are likely to contain sensitive data, such as 15 | # password, private keys, and other secrets. These should not be part of version 16 | # control as they are data points which are potentially sensitive and subject 17 | # to change depending on the environment. 18 | *.tfvars 19 | *.tfvars.json 20 | 21 | # Ignore override files as they are usually used to override resources locally and so 22 | # are not checked in 23 | override.tf 24 | override.tf.json 25 | *_override.tf 26 | *_override.tf.json 27 | 28 | # Include override files you do wish to add to version control using negated pattern 29 | # !example_override.tf 30 | 31 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 32 | # example: *tfplan* 33 | 34 | # Ignore CLI configuration files 35 | .terraformrc 36 | terraform.rc 37 | .terraform.lock.hcl 38 | 39 | 40 | # OSX leaves these everywhere on SMB shares 41 | ._* 42 | 43 | # OSX trash 44 | .DS_Store 45 | 46 | # Developers can store local stuff in dirs named __something 47 | __* 48 | 49 | # Eclipse files 50 | .classpath 51 | .project 52 | .settings/** 53 | 54 | # Files generated by JetBrains IDEs, e.g. IntelliJ IDEA 55 | .idea/ 56 | *.iml 57 | 58 | # Vscode files 59 | .vscode 60 | 61 | # This is where the result of the go build goes 62 | /output*/ 63 | /_output*/ 64 | /_output 65 | 66 | # Emacs save files 67 | *~ 68 | \#*\# 69 | .\#* 70 | 71 | # Vim-related files 72 | [._]*.s[a-w][a-z] 73 | [._]s[a-w][a-z] 74 | *.un~ 75 | Session.vim 76 | .netrwhist 77 | 78 | # cscope-related files 79 | cscope.* 80 | 81 | # Go test binaries 82 | *.test 83 | /hack/.test-cmd-auth 84 | 85 | # JUnit test output from ginkgo e2e tests 86 | /junit*.xml 87 | 88 | # Mercurial files 89 | **/.hg 90 | **/.hg* 91 | 92 | # Vagrant 93 | .vagrant 94 | network_closure.sh 95 | 96 | # Local cluster env variables 97 | /cluster/env.sh 98 | 99 | # Compiled binaries in third_party 100 | /third_party/pkg 101 | 102 | # Also ignore etcd installed by hack/install-etcd.sh 103 | /third_party/etcd* 104 | /default.etcd 105 | 106 | # User cluster configs 107 | .kubeconfig 108 | 109 | .tags* 110 | 111 | # Version file for dockerized build 112 | .dockerized-kube-version-defs 113 | 114 | # Web UI 115 | /www/master/node_modules/ 116 | /www/master/npm-debug.log 117 | /www/master/shared/config/development.json 118 | 119 | # Karma output 120 | /www/test_out 121 | 122 | # precommit temporary directories created by ./hack/verify-generated-docs.sh and ./hack/lib/util.sh 123 | /_tmp/ 124 | /doc_tmp/ 125 | 126 | # Test artifacts produced by Jenkins jobs 127 | /_artifacts/ 128 | 129 | # Go dependencies installed on Jenkins 130 | /_gopath/ 131 | 132 | # Config directories created by gcloud and gsutil on Jenkins 133 | /.config/gcloud*/ 134 | /.gsutil/ 135 | 136 | # CoreOS stuff 137 | /cluster/libvirt-coreos/coreos_*.img 138 | 139 | # Downloaded Kubernetes binary release 140 | /kubernetes/ 141 | 142 | # direnv .envrc files 143 | .envrc 144 | 145 | # Downloaded kubernetes binary release tar ball 146 | kubernetes.tar.gz 147 | 148 | # Phony test files used as part of coverage generation 149 | zz_generated_*_test.go 150 | 151 | # Just in time generated data in the source, should never be committed 152 | /test/e2e/generated/bindata.go 153 | 154 | # This file used by some vendor repos (e.g. github.com/go-openapi/...) to store secret variables and should not be ignored 155 | !\.drone\.sec 156 | 157 | /bazel-* 158 | *.pyc 159 | 160 | # generated by verify-vendor.sh 161 | vendordiff.patch -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rapid-fire Terraforming Kubernetes 2 | This repository is a rapid-fire version of our in-depth tutorial for Terraforming Kubernetes on Linode with [this post](https://www.codingforentrepreneurs.com/blog/terraforming-kubernetes-on-linode/). 3 | 4 | To get started: 5 | 6 | ## Requirements 7 | - [Git](https://git-scm.com/downloads) installed 8 | - [Terraform](https://developer.hashicorp.com/terraform/downloads) installed 9 | - [Kubectl](https://kubernetes.io/docs/tasks/tools/) installed 10 | 11 | ## 1. Clone this repo 12 | 13 | ```bash 14 | git clone https://github.com/codingforentrepreneurs/terraforming-kubernetes-rapid 15 | cd terraforming-kubernetes-rapid 16 | ``` 17 | 18 | Create an account on [Linode](https://www.linode.com/cfe) and get an API Key in your linode account [here](https://cloud.linode.com/profile/tokens). 19 | 20 | Once you have a key, do the following: 21 | 22 | ```bash 23 | echo "linode_api_token=\"YOUR_API_KEY\"" >> terraform.tfvars 24 | ``` 25 | 26 | ## 2. Initialize Terraform 27 | 28 | ```bash 29 | terraform init 30 | ``` 31 | 32 | ## 3. Terraform your Kubernetes Cluster 33 | ```bash 34 | terraform apply 35 | ``` 36 | > Use `terraform apply -auto-approve` if you're really in a hurry. 37 | 38 | ## 4. Set your `KUBECONFIG` Environment Variable 39 | 40 | ```bash 41 | export KUBECONFIG="./.kube/kubeconfig.yaml" 42 | ``` 43 | > If you are using VSCode, the `KUBECONFIG` variable is set in `tf-k8s.code-workspace` settings. 44 | 45 | Verify your `KUBECONFIG` is set correctly: 46 | 47 | ```bash 48 | kubectl get nodes 49 | ``` 50 | 51 | ## 5. Deploy your first app 52 | 53 | ```bash 54 | kubectl apply -f k8s.yaml 55 | ``` 56 | 57 | ## 6. Get your app's IP address 58 | 59 | ```bash 60 | kubectl get service cfe-nginx-service -o "jsonpath={.status.loadBalancer.ingress[0].ip}" 61 | ``` 62 | 63 | Or 64 | ``` 65 | export IP_ADDRESS=$(kubectl get service cfe-nginx-service -o "jsonpath={.status.loadBalancer.ingress[0].ip}") 66 | open http://$IP_ADDRESS 67 | ``` 68 | 69 | ## 7. Celebrate 70 | 71 | _P.S._ Destroy everything with `terraform apply -destroy -auto-approve` to avoid incurring any charges. 72 | -------------------------------------------------------------------------------- /infra.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.15" 3 | required_providers { 4 | linode = { 5 | source = "linode/linode" 6 | } 7 | } 8 | } 9 | 10 | provider "linode" { 11 | token = var.linode_api_token 12 | } 13 | 14 | locals { 15 | root_dir = "${abspath(path.root)}" 16 | k8s_config_dir = "${local.root_dir}/.kube/" 17 | k8s_config_file = "${local.root_dir}/.kube/kubeconfig.yaml" 18 | } 19 | 20 | variable "linode_api_token" { 21 | description = "Your Linode API Personal Access Token. (required)" 22 | sensitive = true 23 | } 24 | 25 | resource "linode_lke_cluster" "terraform_k8s" { 26 | k8s_version="1.25" 27 | label="terraform-k8s" 28 | region="us-east" 29 | tags=["terraform-k8s"] 30 | pool { 31 | type = "g6-standard-1" 32 | count = 3 33 | 34 | } 35 | } 36 | 37 | resource "local_file" "k8s_config" { 38 | content = "${nonsensitive(base64decode(linode_lke_cluster.terraform_k8s.kubeconfig))}" 39 | filename = "${local.k8s_config_file}" 40 | file_permission = "0600" 41 | } 42 | 43 | -------------------------------------------------------------------------------- /k8s.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: cfe-nginx-deployment 6 | spec: 7 | replicas: 3 8 | selector: 9 | matchLabels: 10 | app: cfe-nginx-deployment 11 | template: 12 | metadata: 13 | labels: 14 | app: cfe-nginx-deployment 15 | spec: 16 | containers: 17 | - name: cfe-nginx-container 18 | image: codingforentrepreneurs/cfe-nginx:latest 19 | imagePullPolicy: Always 20 | ports: 21 | - name: cfe-nginx-port 22 | containerPort: 80 23 | 24 | --- 25 | apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: cfe-nginx-service 29 | spec: 30 | selector: 31 | app: cfe-nginx-deployment 32 | type: LoadBalancer 33 | ports: 34 | - protocol: TCP 35 | port: 80 36 | targetPort: cfe-nginx-port 37 | -------------------------------------------------------------------------------- /tf-k8s.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": { 8 | "files.autoSave": "afterDelay", 9 | "terminal.integrated.env.osx": { 10 | "KUBECONFIG": "${workspaceFolder}/.kube/kubeconfig.yaml" 11 | }, 12 | "terminal.integrated.env.windows": { 13 | "KUBECONFIG": "${workspaceFolder}\\.kube\\kubeconfig.yaml" 14 | }, 15 | "terminal.integrated.env.linux": { 16 | "KUBECONFIG": "${workspaceFolder}/.kube/kubeconfig.yaml" 17 | }, 18 | } 19 | } --------------------------------------------------------------------------------