Terraformを使う上で最低限知っていた方がいいと思うことを記載しています。
step2ディレクトリを作成、移動して実施ください。以降のプラクティスはすべてstep2ディレクトリ内で行う想定です。ファイルはステップ内で同じものを続けて使ったください。
Terraformはプロバイダーを使ってリソースのデプロイをします。対応したプロバイダーはこちらにあります。AWSプロバイダーの場合はリソースをデプロイするリージョンを設定できます。設定はproviderブロックに書きます。providerブロックもどこに書いても良いですが、versions.tfファイルに書くのがよいでしょう。
プラクティス
- Provider Configurationを参考に以下内容を
versions.tfに追加してください。awsプロバイダーの設定ブロックで東京リージョン(ap-northeast-1)を指定します(任意の別リージョンでも良いです)
ヒント: ステップ1の設定をまねてください。
Terraform自体とクラウドプロバイダーのバージョンに要件を設定できます。これはterraformブロックで設定します。例えばTerraformとAWSプロバイダーのバージョンを2023/1時点の最新であるTerraform:1.3.7、AWSプロバイダー:4.49.0以上といった指定ができます。
Terraformおよびクラウドプロバイダーは活発に開発が行われており、バージョン違いで意図した動作をしないことが懸念されます。そのため、terraformブロックで使用するバージョン要件を設定した方がいいです。
terraformブロックはどのファイルに書いてもいいですがversions.tfファイルに書くのがよいでしょう。
プラクティス
- Terraform Settingsを参考に以下内容の
versions.tfを作成してください。- AWSプロバイダーのバージョンを
4.49.0以上を要件に指定します。
- AWSプロバイダーのバージョンを
ヒント: ステップ1の設定をまねてください。
Terraformはクラウドプロバイダーを使用してリソースをデプロイします。たとえばAWSの場合、AWSプロバイダーにTerraformでデプロイできるリソースが載っています。デプロイしたいリソースをresourceブロックに記述してデプロイします。各リソースには設定可能なパラメーターが数多く用意されています。リソースごとに必須のパラメーターとオプションのパラメーターがあります。指定しなかったオプションパラメーターはデフォルト値でデプロイされます。すべてのパラメーターを記述してもいいですが大変です。明示的にデフォルトから変えたいパラメーターのみ書くのが良いと思います。本プラクティスでは明示的に指定しているパラメーター以外は指定なし(デフォルト値)で良いです。
プラクティス
- Resource: aws_vpcを参考に以下内容の
main.tfファイルを作成します。- リソースタイプ:aws_vpc リソース名:tf_test
- CIDRブロック:10.1.0.0/16
- Name:tf-test、Env:terraform-practice、Owner:自分の名前 のタグを設定
- initしてplanで内容を確認しapplyします。
- マネージメントコンソールまたは以下コマンドでリソースが作成されたことを確認します。
$ aws ec2 describe-vpcs --filters "Name=tag-value,Values=tf-test"つづいて作成したVPCにサブネットを追加します。サブネットはResource: aws_subnetで宣言します。サブネットを作成する際、vpc_idの指定が必須です。VPCのIDを自分で確認して入力するのは手間です。Terraformでは作成したリソースの情報(属性)を別リソースから参照できます。VPCの場合、Resource: aws_vpc の Attributes Referenceに書かれている属性を別リソースから参照できます。別リソースからはリソースタイプ.リソース名.属性名で参照できます。
プラクティス
- Resource: aws_subnetを参考に以下内容を
main.tfに追加します。- リソースタイプ:aws_subnet リソース名:tf_test
- vpc_id:aws_vpc.tf_testのIDを参照
- CIDRブロック:10.1.10.0/24
- Name:tf-test、Env:terraform-practice、Owner:自分の名前 のタグを設定
- planしてapplyします。
- マネージメントコンソールまたは以下コマンドでリソースが作成されたことを確認します。
$ aws ec2 describe-subnets --filters "Name=tag-value,Values=tf-test"値を変数にして外だしすることもできます。後のStepであつかうモジュール化をする場合によく使います。変数化したい値ごとにvaliablesブロックで記述します。valiablesブロックもどこに書いてもいいですが、valiables.tfファイルにまとめて書くのがよいでしょう。valiablesブロックで宣言した変数はリソース内でvar.名前と指定すれば参照できます。文字列の中に変数を埋め込みたい場合は${var.名前}と書くと文字列に変数を入れられます。valiabelsブロックにはtypeが指定でき値の制限ができます。基本的にtypeは指定するようにしましょう。また、descriptionで値の説明を書けます。基本的にdescriptionも記述するようにしましょう。
variablesブロックで宣言した変数に値を設定するにはいくつかの方法があります。terraform.tfvarsファイルに変数名=値の形式で指定することが多いと思います。
プラクティス
variables.tfファイルを作成し以下内容のvariablesブロックを記述します。- 変数名: subnet_cidr
- タイプ: 文字列
- 説明: サブネットのCIDRです
terraform.tfvarsファイルを作成し、subnet_cidrに10.1.10.0/24を設定します。main.tfのaws_subnet.tf_testのcidr_blockを変数subnet_cidrから読みこむようにします。- planします。
No changes.となり変更がないことを確認します。 terraform.tfvarsファイルのsubnet_cidrに10.1.20.0/24に変更します。- planしてサブネットが
replacedされることを確認し、applyします。
作成したVPCやサブネットにはEnvやOwnerなど、同じタグが設定されています。こういったすべてのリソースに設定したいタグはdefault_tagsで設定すると楽です。default_tagsはproviderブロックで設定します。
プラクティス
varsions.tf内のAWSプロバイダー設定にて、Env:terraform-practice、Owner:自分の名前 のデフォルトタグを設定しますmain.tfのvpcおよびsubentからEnvとOwnerのタグを消します- planします。このとき、tagsの部分のみに差分が出ることを確認します
- 確認後applyします
- マネージメントコンソールまたは以下コマンドで"2-3. リソース間で値を渡す"で表示されたリソースがそのまま表示されること確認します。
$ aws ec2 describe-subnets --filters "Name=tag-value,Values=tf-test"Terraformで作成したリソースの情報(ARNやIDなど)を確認するにはoutputブロックに記述します。outputブロックもどこに書いてもいいですが、ouput.tfファイルにまとめて書くのがいいでしょう。outputする値の指定はリソースの属性参照と同じくリソースタイプ.リソース名.属性名です。また、属性名を省略しリソースタイプ.リソース名と指定すると、そのリソースのすべての属性を表示できます。
プラクティス
output.tfファイルを作成し以下内容のoutputブロックを記述します。- vpc_id: vpcのid
- vpc_arn: vpcのarn
- subnet: subnetのすべて属性
- planしてapplyします。applyしたあとoutputが表示されます。
terraform outputするとoutputした値を確認できます。
Terraformを実行したディレクトリを見るとterraform.tfstateとterraform.tfstate.backupというファイルがあります。これらのファイルはTerraformがデプロイしたリソースを記録するものです。中身を確認するとJSON形式でデプロイしたリソースの情報が書かれています。このファイルはとても大事です。**絶対に消さないようにしましょう。**もし消してしまった場合、今までデプロイしたリソースはTerraformの管理外となってしまいます。
プラクティス
試しにterraform.tfstateを消してみます。この操作は学習目的のものです。実運用では絶対にしないでください。
terraform.tfstateを削除します。terraform.tfstate.backupを別ディレクトリ等に退避します。- planします。VPCおよびサブネットが
作成されることを確認します。
planすると作成になりました。つまり、Terraform的には今まで作成したVPCやサブネットはなかったことになっています。このままapplyします。
- applyします。
- マネージメントコンソールまたは以下コマンドでVPCおよびサブネットを確認します。それぞれ2つずつ表示されます。
$ aws ec2 describe-vpcs --filters "Name=tag-value,Values=tf-test"
$ aws ec2 describe-subnets --filters "Name=tag-value,Values=tf-test"VPCはCIDRが同じでもデプロイできるためVPCおよびサブネットがもう1セット作成されました。このように、tfstateファイルがなくなると以前のリソースをTerraformで管理できなくなります。そのため、tfstateファイルは絶対なくさないようにします。
また、複数人でTerraformを使って環境を管理する場合、このtfstateファイルを共有した方がよいです。その場合、tfstateファイルを外部のバックエンドに保存して共有します。バックエンドにはS3が使えるため、S3に保管しつつバージョニングを有効にしてtfstateファイルを保護します。さらにtfstateが同時に更新されることを防ぐために排他制御もした方がいいです。これらについては別のステップにてあつかいます。
terraform destroyで新しいリソースを削除します。- 退避させた
terraform.tfstate.backupをterraform.tfstateとして戻します。
Terraformを実行したディレクトリを見ると隠しディレクトリとして.terraformが作成されています。これはterraform initした時に作成されたもので、この中にはプロバイダーを管理するための情報やtfstateのバックエンド情報が格納されています。このディレクトリはそれなりに容量があります。TerraformをGitで共有する場合、この.terraformディレクトリをGitに含めないように.gitignoreを設定した方がいいです。GitHubやGitLabには.gitignoreのテンプレートでterraofromがあり、そのテンプレートを使えば.terraformが除外されるように設定さますので活用しましょう。
プラクティス
- ディレクトリ内に
.terraformがあることを確認します。
Terraformで作成したリソースはdestroy以外にも削除する方法があります。リソースをコメントアウトして再度applyするとコメントアウトしたリソースを消すことができます。これだとコメントアウトしたリソースだけ削除できます。destroyだと誤ってすべてのリソースを削除してしまうかもしれないため、複数のリソースが含まれる場合はこの方法の方がいいかもしれません。コメントアウトの仕方はこちらのCommentsにあります。
プラクティス
main.tf内のvpcおよびsubnetをコメントアウトします。output.tf内のvpcおよびsubnetの出力する部分をコメントアウトします。- planしてapplyします。リソースが削除されます。
今回はvpcとsubentを同時に削除しましたが、subnet部分だけコメントアウトしてapplyするとsubnetだけ削除できます。
- destroyします。またはmain.tfをすべてコメントアウトしてapplyします。