https://www.youtube.com/watch?v=0IQ4IScqQws&t=212s https://caddi.tech/archives/4320
terraform とは
公式ドキュメントです。読まないと…。
url: https://developer.hashicorp.com/terraform
title: "Terraform | HashiCorp Developer"
description: "Explore Terraform product documentation, tutorials, and examples."
host: developer.hashicorp.com
favicon: https://developer.hashicorp.com/favicon.ico
image: https://developer.hashicorp.com/og-image/terraform.jpg
terraform の第一歩がわかりやすく書かれています。
url: https://zenn.dev/oyasumipants/articles/6f8c03380d7171
title: "Terraform に入門する"
host: zenn.dev
image: https://res.cloudinary.com/zenn/image/upload/s--E_ibeTkq--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:Terraform%2520%25E3%2581%25AB%25E5%2585%25A5%25E9%2596%2580%25E3%2581%2599%25E3%2582%258B%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_37:KeigoIbaraki%2Cx_203%2Cy_121/g_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzZkZjFhM2RlZjkuanBlZw==%2Cr_max%2Cw_90%2Cx_87%2Cy_95/v1627283836/default/og-base-w1200-v2.png
terraform の基本やスタイルガイド・モジュールなどあらゆることがわかりやすく書かれており、とりあえずこちらを見たほうがよさそうです。
url: https://speakerdeck.com/emiki/terraform-this-and-that
title: "Terraformあれやこれ/terraform-this-and-that"
description: "2024/4/19(金)JAWS-UG朝会 #56https://jawsug-asa.connpass.com/event/312976/登壇資料です。"
host: speakerdeck.com
favicon: https://d1eu30co0ohy4w.cloudfront.net/assets/favicon-bdd5839d46040a50edf189174e6f7aacc8abb3aaecd56a4711cf00d820883f47.png
image: https://files.speakerdeck.com/presentations/878ebc08f3554cc8969086bf6ce0c911/slide_0.jpg?31391084
terraform における drift の解決方法など、基本から応用までわかりやすく説明されています。
url: https://caddi.tech/archives/4320
title: "第3回: Terraformの基本とステート管理 - CADDi Tech Blog"
description: "※本記事は、技術評論社「Software Design」(2023年6月号)に寄稿した連載記事「Google Cloudで実践するSREプラクティス」からの転載です。発行元からの許可を得て掲載しております。 はじめに 前回はIaCの考え方や必要性と、筆者らが採用しているTerraformの特徴について紹介しました。今回は今後紹介するプラクティスの前提となるTerraformに触れたことのない方のために、その基本を簡単に紹介します1。 ここで紹介できない事項やTerraformのインストール方法については、HashiCorp 社やGoogleCloudのチュートリアル2を参考にしてください。ぜひ…"
host: caddi.tech
favicon: https://caddi.tech/icon/link
image: https://cdn.image.st-hatena.com/image/scale/5556d88c5f458a98d86fafbbf99e917f1b37493a/backend=imagemagick;version=1;width=1300/https%3A%2F%2Fcaddi.tech%2Fwp-content%2Fuploads%2F2023%2F07%2FTerraform-basic.drawio.png
terraform の設計をどうすべきか
第一に Standard Module Structure (Official) を参考にします。
url: https://developer.hashicorp.com/terraform/language/modules/develop/structure
title: "Standard Module Structure | Terraform | HashiCorp Developer"
description: "Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories."
host: developer.hashicorp.com
favicon: https://developer.hashicorp.com/favicon.ico
image: https://developer.hashicorp.com/og-image/terraform.jpg
続いて、GCP ならびに Future さんの設計ガイドラインを参考にします。
url: https://cloud.google.com/docs/terraform/best-practices/general-style-structure?hl=ja
title: "一般的なスタイルと構造に関するベスト プラクティス | Terraform | Google Cloud"
host: cloud.google.com
image: https://cloud.google.com/_static/cloud/images/social-icon-google-cloud-1200-630.png?hl=ja
url: https://future-architect.github.io/arch-guidelines/documents/forTerraform/terraform_guidelines.html
title: "Terraform設計ガイドライン | フューチャー株式会社"
description: "フューチャー株式会社の有志が作成する<wbr>良いアーキテクチャを実現するための設計ガイドライン"
host: future-architect.github.io
favicon: https://future-architect.github.io/arch-guidelines/favicon.ico
また、下記の講演も非常にわかりやすいです。 State 管理・ファイル・ディレクトリ管理など、 terraform のベストプラクティスがきれいにまとめられています。
url: https://www.youtube.com/watch?v=0IQ4IScqQws
title: "I-2 : 「それ、どこに出しても恥ずかしくないTerraformコードになってるか?」"
description: "✨講師:吉田 祐樹 (アマゾン ウェブ サービス ジャパン合同会社 Professional Services)✨セッション概要: ある日、父にこんなことを言われたあなたは考えます。そういえばMartin Fowlerもこんなことを言っていたな。。。「コンパイラがわかるコードは誰にでも書ける。すぐれたプログラマは..."
host: www.youtube.com
favicon: https://www.youtube.com/s/desktop/ba3a814f/img/logos/favicon_32x32.png
image: https://i.ytimg.com/vi/0IQ4IScqQws/maxresdefault.jpg?sqp=-oaymwEmCIAKENAF8quKqQMa8AEB-AHUBoAC4AOKAgwIABABGH8gMCg6MA8=&rs=AOn4CLA1OluZwhX6MNIjID0rIQ3jWIUQbQ
terraform で疑問に思ったこととその答え
ChatGPT 含む AI ツールに聞いています。
ファイル名に制約はあるのか
terraform ではディレクトリにある *.tf
をすべて読み込み 1 つの構成として扱います。
ここで、ファイルは
- network.tf
- compute.tf
- database.tf
のように役割で分割することが推奨されているようです。
よって、必ずしも main.tf が必要である、というわけではありません。 エントリーポイントとして main.tf が利用されるようです。
https://speakerdeck.com/hiyanger/terraform-yarunarasutairugaidowodu-mou-zhong-yao-xiang-mu-10xuan
ディレクトリ構成をどうすべきか?
https://developer.hashicorp.com/terraform/language/modules/develop/structure https://dev.classmethod.jp/articles/terraform_speaker_report_jawsug_tokyo/
環境ごとにディレクトリを切り、その環境の main.tf で必要なモジュールをインポートするのがよいようです。
そして modules
で各モジュールにあうディレクトリを切ります。
.
├── environments/
│ ├── production/
│ │ ├── main.tf
│ │ └── terraform.tfvars
│ └── staging/
│ ├── main.tf
│ └── terraform.tfvars
└── modules/
├── vpc/
│ ├── main.tf
│ └── ...
└── webapp/
├── main.tf
└── ...
variables.tf とは?
terraform で利用する変数を多くの場合 variables.tf
で宣言します。
variable "instance_type" {
type = string
default = "t2.micro"
}
明確には variables.tf
という名前でなくてもよいです。
main.tf などに変数を定義してもよいです。
.tfvars とは?
variables.tf
で定義した変数について、実際に値を設定するファイルです。
-var-file=
で指定します。
aws_access_key = "XXXXXXXXXXXXXXXXXXXX"
aws_secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
outputs.tf とは?
network/output.tf に下記のように定義していたとします。
output "instance_ip" {
value = aws_instance.example.public_ip
}
このとき、上記を environment/dev/main.tf で webapp/hoge.tf に引き渡すことで、ネットワークの IP を webapp に渡せます。 詳しくは https://dev.classmethod.jp/articles/terraform_speaker_report_jawsug_tokyo/ にあります。
tfstate とは?
https://zenn.dev/spacemarket/articles/b7bd1422b896ca https://zenn.dev/sway/articles/terraform_biginner_tfstate
terraform が管理するインフラの状態を管理する JSON ファイルです。 terraform は
- Desired State
- 各種 tf ファイルによって宣言された構成
- Real State
- GCP, AWS 上にある実際のインフラ
- tfstate
- 前回の terraform コマンド実行時のインフラ状態を記録した JSON
を比べたうえでおこなうべき変更を apply します。
- tfstate と Desired State (tf ファイル) を比べて、どのような変更をしたいのかを見つける
- tfstate に記録されている Resource ID をもとに、GCP/AWS に問い合わせて実際の状態を取得する
- 3状態すべてを考慮したうえで、変更内容を決める
という流れです。
tfstate の記事を試す
https://zenn.dev/sway/articles/terraform_biginner_tfstate を試したところ、 hello.tf
によって生成された tfstate は以下のようになっていました。
- terraform の version
- resource の状態
- name: helloworld
- provider: local
- instance
- text: hello world
が入っています。
resource "local_file" "helloworld" {
content = "hello world!"
filename = "hello.txt"
file_permission = "0777"
}
{
"version": 4,
"terraform_version": "1.12.2",
"serial": 1,
"lineage": "7a8ec19f-7c87-93bd-9d95-5d0797d86b96",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "local_file",
"name": "helloworld",
"provider": "provider[\"registry.terraform.io/hashicorp/local\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"content": "hello world!",
"content_base64": null,
"content_base64sha256": "dQnlvaDHYtK6x/kNdYtbImP6Acy8VCq1498WO+CObKk=",
"content_base64sha512": "25sc0yYt7jd1agm5BklzWJhHyqjlPTGp0ULqJwGxsoq9l4OLuaJwaLowXcjQSkWh/PB53lTWB2ZplrPMVPa2fA==",
"content_md5": "fc3ff98e8c6a0d3087d515c0473f8677",
"content_sha1": "430ce34d020724ed75a196dfc2ad67c77772d169",
"content_sha256": "7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9",
"content_sha512": "db9b1cd3262dee37756a09b9064973589847caa8e53d31a9d142ea2701b1b28abd97838bb9a27068ba305dc8d04a45a1fcf079de54d607666996b3cc54f6b67c",
"directory_permission": "0777",
"file_permission": "0777",
"filename": "hello.txt",
"id": "430ce34d020724ed75a196dfc2ad67c77772d169",
"sensitive_content": null,
"source": null
},
"sensitive_attributes": [
[
{
"type": "get_attr",
"value": "sensitive_content"
}
]
],
"identity_schema_version": 0
}
]
}
],
"check_results": null
}
.terraform ディレクトリには必要になる provider (local) のバイナリが入っていました。
強引に hello.txt を hello WORLD! に書き換えてから terraform plan したところ、 desired と tfstate の差分が検知され、変更予定の内容が表示されました。
apply すると hello, world!
にちゃんと修正されます。
hello WORLD!
❯ terraform plan
local_file.helloworld: Refreshing state... [id=430ce34d020724ed75a196dfc2ad67c77772d169]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# local_file.helloworld will be created
+ resource "local_file" "helloworld" {
+ content = "hello world!"
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "hello.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
続いて hello, world!
の状態で terraform.tfstate
を削除しました。
その状態で plan すると下記のように差分がある、とのように表示されました。
これは
- hello.txt には
hello, world!
というテキストは正しく入っている - しかし、 terraform.tfstate がないため terraform は未実行だと判断している
とわかります。
❯ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# local_file.helloworld will be created
+ resource "local_file" "helloworld" {
+ content = "hello world!"
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "hello.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroyy
apply するとファイルが更新されたようです。
Enter a value: yes
local_file.helloworld: Creating...
local_file.helloworld: Creation complete after 0s [id=430ce34d020724ed75a196dfc2ad67c77772d169]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
このように tfstate を消してしまうと実際にリソースが存在したとしても作り直してしまうため、ちゃんと S3 / GCS などの backend に tfstate を保存しないと駄目ですね。
providers.tf とは?
GCP, AWS など、各プロバイダーごとに設定したい内容を記述します。 provider block で記述します。
terraform block とは?
providers block とは対象的に、 terraform 全体とした設定を記述します。 必要になるプロバイダプラグインの指定や backend file を指定します。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "production/terraform.tfstate"
region = "ap-northeast-1"
}
required_version = "~> 1.0"
}
linter / test をどうするのがよいか
linter
https://github.com/terraform-linters/tflint
tflint という terraform の linter があります。 これを利用してベストプラクティスにそった tf になっているか?を CD でチェックするのがよさそうです。
https://www.checkov.io/ checkov というセキュリティチェックツールもあるようですが個人であれば導入しなくてもよいですね。
test
https://zenn.dev/kyohei_saito/articles/a32b5a11c81e97
terraform test というコマンドがあり plan → apply を実際に実行して想定どおりの変更になっているか? を assert できるようです。 こちらは個人で導入してもよさそうですね。