Terraformの練習をローカルで完結させるのにk8sが手軽で良かった
Terraformを試すときに困ったこと
サクッとTerraformを試してみたいと思ったときに悩む要素の一つがProviderの準備かと思います。
ベタなのはAWS/Azure/Google Cloud Platformあたりだと思います。ただそのためにわざわざアカウント作るのも手間だし、何よりTerraformを試したいだけなのにコストやセキュリティのことを心配したくないなと億劫になっていました。
Ansibleを使っていた頃はVagrant + VirtualBoxで簡単に実行先を作れたんですが、Terraformの場合どうするのがいいかと思ってProvider一覧を見ていたんですがKubernetesが意外といいんじゃないかと思い試してみました。
環境準備
1% sw_vers
2ProductName: macOS
3ProductVersion: 13.0.1
4BuildVersion: 22A400
TerraformのインストールはHomebrewで行います。
1brew tap hashicorp/tap
2brew install hashicorp/tap/terraform
1[koh@Kohs-MacBook-Pro-M1-387] ~
2% terraform --version
3Terraform v1.3.7
4on darwin_arm64
5[koh@Kohs-MacBook-Pro-M1-387] ~
6%
KubernetesはDocker Desktop for Macを利用します。
インストールした後にKubernetesをenableするとローカルで利用できるようになります。
1[koh@Kohs-MacBook-Pro-M1-387] ~
2% kubectl config get-contexts
3CURRENT NAME CLUSTER AUTHINFO NAMESPACE
4* docker-desktop docker-desktop docker-desktop
5[koh@Kohs-MacBook-Pro-M1-387] ~
6% kubectl get all
7NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
8service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 110d
9[koh@Kohs-MacBook-Pro-M1-387] ~
10%
動作確認
まずは適当なディレクトリを作成します。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work
2% mkdir terraform-with-k8s
3[koh@Kohs-MacBook-Pro-M1-387] ~/work
4% cd !$
5cd terraform-with-k8s
6[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
7%
ここからドキュメントをもとにTerraformを書いていきます。
最初にmain.tfを用意し、Example Usageの内容をコピペします。
ローカルのDocker Desktopを利用するためconfig_contextを docker-desktop
に変更します。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% cat main.tf
3provider "kubernetes" {
4 config_path = "~/.kube/config"
5 config_context = "docker-desktop"
6}
7
8resource "kubernetes_namespace" "example" {
9 metadata {
10 name = "my-first-namespace"
11 }
12}
13[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
14%
terraform init
によりKubernetes Providerをインストールします。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% terraform init
3
4Initializing the backend...
5
6Initializing provider plugins...
7- Finding latest version of hashicorp/kubernetes...
8- Installing hashicorp/kubernetes v2.16.1...
9- Installed hashicorp/kubernetes v2.16.1 (signed by HashiCorp)
10
11Terraform has created a lock file .terraform.lock.hcl to record the provider
12selections it made above. Include this file in your version control repository
13so that Terraform can guarantee to make the same selections by default when
14you run "terraform init" in the future.
15
16Terraform has been successfully initialized!
17
18You may now begin working with Terraform. Try running "terraform plan" to see
19any changes that are required for your infrastructure. All Terraform commands
20should now work.
21
22If you ever set or change modules or backend configuration for Terraform,
23rerun this command to reinitialize your working directory. If you forget, other
24commands will detect it and remind you to do so if necessary.
25[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
26%
terraform plan
でドライランします。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% terraform plan
3
4Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
5symbols:
6 + create
7
8Terraform will perform the following actions:
9
10 # kubernetes_namespace.example will be created
11 + resource "kubernetes_namespace" "example" {
12 + id = (known after apply)
13
14 + metadata {
15 + generation = (known after apply)
16 + name = "my-first-namespace"
17 + resource_version = (known after apply)
18 + uid = (known after apply)
19 }
20 }
21
22Plan: 1 to add, 0 to change, 0 to destroy.
23
24───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
25
26Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run
27"terraform apply" now.
28[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
29%
terraform apply
で実際に適用します。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% terraform apply
3
4Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
5symbols:
6 + create
7
8Terraform will perform the following actions:
9
10 # kubernetes_namespace.example will be created
11 + resource "kubernetes_namespace" "example" {
12 + id = (known after apply)
13
14 + metadata {
15 + generation = (known after apply)
16 + name = "my-first-namespace"
17 + resource_version = (known after apply)
18 + uid = (known after apply)
19 }
20 }
21
22Plan: 1 to add, 0 to change, 0 to destroy.
23
24Do you want to perform these actions?
25 Terraform will perform the actions described above.
26 Only 'yes' will be accepted to approve.
27
28 Enter a value: yes
29
30kubernetes_namespace.example: Creating...
31kubernetes_namespace.example: Creation complete after 0s [id=my-first-namespace]
32
33Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
34[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
35%
kubectl get namespace
でnamespaceが作成されていることがわかります。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% kubectl get namespace
3NAME STATUS AGE
4default Active 110d
5kube-node-lease Active 110d
6kube-public Active 110d
7kube-system Active 110d
8my-first-namespace Active 16s
9[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
10%
ここでnamespaceの名前をmy-second-namespace
に更新してplanしてみます。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% cat main.tf
3provider "kubernetes" {
4 config_path = "~/.kube/config"
5 config_context = "docker-desktop"
6}
7
8resource "kubernetes_namespace" "example" {
9 metadata {
10 name = "my-second-namespace"
11 }
12}
13[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
14% terraform plan
15kubernetes_namespace.example: Refreshing state... [id=my-first-namespace]
16
17Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
18symbols:
19-/+ destroy and then create replacement
20
21Terraform will perform the following actions:
22
23 # kubernetes_namespace.example must be replaced
24-/+ resource "kubernetes_namespace" "example" {
25 ~ id = "my-first-namespace" -> (known after apply)
26
27 ~ metadata {
28 - annotations = {} -> null
29 ~ generation = 0 -> (known after apply)
30 - labels = {} -> null
31 ~ name = "my-first-namespace" -> "my-second-namespace" # forces replacement
32 ~ resource_version = "7148807" -> (known after apply)
33 ~ uid = "3c73d846-24c1-45b7-9e58-ad99c5c275c7" -> (known after apply)
34 }
35 }
36
37Plan: 1 to add, 0 to change, 1 to destroy.
38
39───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
40
41Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run
42"terraform apply" now.
43[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
44%
namespaceの名前を変更したことにより再作成されます。
ちなみにforces replacement
は一度リソースを削除してから新規で作成するという意味なので、状況によっては注意が必要です。
実際にapplyすると my-first-namespace
が削除され、my-second-namespace
が作成されることがわかります。
1[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
2% terraform apply
3kubernetes_namespace.example: Refreshing state... [id=my-first-namespace]
4
5Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
6symbols:
7-/+ destroy and then create replacement
8
9Terraform will perform the following actions:
10
11 # kubernetes_namespace.example must be replaced
12-/+ resource "kubernetes_namespace" "example" {
13 ~ id = "my-first-namespace" -> (known after apply)
14
15 ~ metadata {
16 - annotations = {} -> null
17 ~ generation = 0 -> (known after apply)
18 - labels = {} -> null
19 ~ name = "my-first-namespace" -> "my-second-namespace" # forces replacement
20 ~ resource_version = "7148807" -> (known after apply)
21 ~ uid = "3c73d846-24c1-45b7-9e58-ad99c5c275c7" -> (known after apply)
22 }
23 }
24
25Plan: 1 to add, 0 to change, 1 to destroy.
26
27Do you want to perform these actions?
28 Terraform will perform the actions described above.
29 Only 'yes' will be accepted to approve.
30
31 Enter a value: yes
32
33kubernetes_namespace.example: Destroying... [id=my-first-namespace]
34kubernetes_namespace.example: Destruction complete after 6s
35kubernetes_namespace.example: Creating...
36kubernetes_namespace.example: Creation complete after 0s [id=my-second-namespace]
37
38Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
39[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
40% kubectl get namespace
41NAME STATUS AGE
42default Active 110d
43kube-node-lease Active 110d
44kube-public Active 110d
45kube-system Active 110d
46my-second-namespace Active 5s
47[koh@Kohs-MacBook-Pro-M1-387] ~/work/terraform-with-k8s
48%
まとめ
環境構築からterraform applyまでローカルで完結できました。
これでTerraform初心者でも気軽に色々試せるのでいいなと思いました。