Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kuritka/tf-associate
https://github.com/kuritka/tf-associate
Last synced: 24 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/kuritka/tf-associate
- Owner: kuritka
- Created: 2023-09-01T09:46:37.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2023-09-06T07:09:20.000Z (about 1 year ago)
- Last Synced: 2024-10-04T11:41:24.491Z (about 1 month ago)
- Language: HCL
- Size: 32.2 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# TerraformAssociate
## 1 - Import command , Import Block
- https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace
```shell
kubectl create ns us-east-1a
kubectl create ns us-east-1b
kubectl create ns us-east-1c
``````tf
# import.tf
# terraform requires snake_case for the resource name
import {
to = kubernetes_namespace.us_east_1a
id = "us-east-1a"
}
import {
to = kubernetes_namespace.us_east_1b
id = "us-east-1b"
}
import {
to = kubernetes_namespace.us_east_1c
id = "us-east-1c"
}
``````shell
# create a file generated.tf with the namespaces configuration
terraform plan -generate-config-out=generated.tfterraform plan -out=import_blocks.tfplan
# Plan: 3 to import, 0 to add, 0 to change, 0 to destroy.terraform apply import_blocks.tfplan
# kubernetes_namespace.us-east-1b: Importing... [id=us-east-1a]
# kubernetes_namespace.us-east-1b: Import complete [id=us-east-1a]
# kubernetes_namespace.us-east-1c: Importing... [id=us-east-1a]
# kubernetes_namespace.us-east-1c: Import complete [id=us-east-1a]
# kubernetes_namespace.us-east-1a: Importing... [id=us-east-1a]
# kubernetes_namespace.us-east-1a: Import complete [id=us-east-1a]# Apply complete! Resources: 3 imported, 0 added, 0 changed, 0 destroyed.
```# 2 - Moving into modules
Since I decided to extend the infrsatructure to another region, I extracted the resources into a module. Although I didn't make any changes, resourcy wanted to join because their name was changed from `kubernetes_namespace.us_east_1c` to `module.cluster.kubernetes_namespace.us_east_1c`
```shell
Plan: 3 to add, 0 to change, 0 to destroy.
```
What must be done is to remove the resources and import them again or use the `mv` command.```shell
terraform state mv kubernetes_namespace.us_east_1c module.cluster.kubernetes_namespace.us_east_1c
# Move "kubernetes_namespace.us_east_1c" to "module.cluster.kubernetes_namespace.us_east_1c"
Successfully moved 1 object(s).terraform state mv kubernetes_namespace.us_east_1b module.cluster.kubernetes_namespace.us_east_1b
terraform state mv kubernetes_namespace.us_east_1a module.cluster.kubernetes_namespace.us_east_1a
```Because I did changes in annotations the `plan` command does only changes.
```shell
terraform plan -var-file=us-east.tfvars -out=us-east.tfplan
Plan: 0 to add, 3 to change, 0 to destroy.
```If for some reason you keep import blocks, you have to refactor them as well:
```tf
# from
import {
to = kubernetes_namespace.us_east_1c
id = "us-east-1c"
}# to
import {
to = module.cluster.kubernetes_namespace.us_east_1c
id = "us-east-1c"
}
```# 3 - Backend in Kubernetes Cluster
I tried terraform cloud. Unfortunately it is unusable for demos on local k3d clusters. The problem is that the `terraform plan`
runs on a host machine that can't connect to my local clusters. If the demo was in AWS it would be a very good choice, due to
the wide range of workspace settings, Variable sets and integration with github workflows.
To continue my demo on local k8s clusters - without AWS, I decided to use a local k8s cluster as a backend.- https://developer.hashicorp.com/terraform/language/settings/backends/kubernetes
-
```tf
terraform {
backend "kubernetes" {
secret_suffix = "state"
config_path = "~/.kube/config"
namespace = "backend-state"
config_context = "k3d-backend"
}
}
```Backend state is stored as base64 encoded string in a secret
```shell
# move state to backend
❯ terraform init❯ k get secrets -A --context=k3d-backend
NAMESPACE NAME TYPE DATA AGE
kube-system k3s-serving kubernetes.io/tls 2 5m37s
kube-system k3d-backend-server-0.node-password.k3s Opaque 1 5m36s
kube-system k3d-backend-agent-0.node-password.k3s Opaque 1 5m32s
backend-state tfstate-default-state Opaque 1 60s❯ terraform plan -var-file=us-east.tfvars -out=us-east.tfplan
module.cluster.kubernetes_namespace.us_east_1a: Refreshing state... [id=us-east-1a]
module.cluster.kubernetes_namespace.us_east_1c: Refreshing state... [id=us-east-1c]
module.cluster.kubernetes_namespace.us_east_1b: Refreshing state... [id=us-east-1b]
```_* For reverting back to local state follow these instructions: https://github.com/hashicorp/terraform/issues/33214#issuecomment-1553223031_
# 4 - Mutiple environments
![Screenshot 2023-09-04 at 10 59 18](https://github.com/kuritka/_helper/assets/7195836/839ca7ba-d2f4-4b93-b2e8-bd5042a02404)
- https://cloudcasts.io/course/terraform/environment-directories
Multiple environments can be done between git branches / folders / repos / workspaces (short-living). I chose the easiest way but a bit more difficult to maintain. Each environment or cluster has its own configuration and backend state. It is possible to extract tfvars and backend configurations to root , but terraform init will then require the `-chdir` argument
![Screenshot 2023-09-04 at 11 00 07](https://github.com/kuritka/_helper/assets/7195836/6057763c-8beb-493c-a141-4939130cc628)
```shell
# init migrate to backend automatically and clean terraform.tfstate
terraform init
terraform plan -var-file=eu-west.tfvars -out=.out.tfplan
terraform apply .out.tfplan...
terraform plan -var-file=us-east.tfvars -out=.out.tfplan
...
```
The problem is it is not DRY!# 5 - workspaces
# workspace
Thanks to workspace I can physically create more statefiles and thanks to that I can switch between different environments. This is good for testing, but as mentioned in drive, you need a good separation of contexts in the individual environments.I can imagine if we do in the workspaces east + west, but the environments (dev, uat, prod) will be separated by directories. Respectively, from dev, files will be copied to `generated_*.tf` while *.tf will serve as overrides in the higher environments. Thats how I can manage large projects in terraform.
![Screenshot 2023-09-05 at 12 02 22](https://github.com/kuritka/_helper/assets/7195836/63f436eb-acf0-49bf-b320-5dbb7d69f9ac)
![Screenshot 2023-09-05 at 12 20 40](https://github.com/kuritka/_helper/assets/7195836/ad7427b8-9a87-4303-b870-da880623b65c)
```shell
terraform workspace new west
terraform init
terraform plan -var-file=_west.tfvars -out=.out.west.tfplan
terraform apply .out.west.tfplanterraform workspace new east
terraform init
terraform plan -var-file=_east.tfvars -out=.out.east.tfplan
terraform apply .out.east.tfplan
```## TODO: Robust Design
combine workspace and environment. West and East clusters will be divided by workspace. Symlinks don't work well in terraform cloud so make a
process to copy files with prefix generated_ to higher environments. The rest of the .tf files will be overrides. If that's too hard, experiment with git branches