terraformの構文とかまとめ
2023-11-21
terraform現場でterraformでのIaCを経験したのでざっくりメモです
複数アカウントの切り替え
AWS cliのconfigure登録でアカウントごとに--profile
オプションをつけて作成する
export AWS_DEFAULT_PROFILE=prod
などで切り替え
1$ aws configure --profile <YOUR_PROFIlE_ID> 2 3AWS Access Key ID [None]: <YOUR_ACCESS_KEY> 4AWS Secret Access Key [None]: <YOUR_SECRET_ACCESS_KEY> 5Default region name [None]: <YOUR_REGION> 6Default output format [None]:
1$ export AWS_DEFAULT_PROFILE=prod
他にもワークスペース機能を活用したり出来るらしい(まだ使用したことが無いです…)
terraformコマンド操作説明
初期化 Terraformで新しく設定を記述した場合、初期化を行う必要があります。
1$ terraform init
確認(所謂dry-run) 実行計画の確認ができます
1$ terraform plan
適用
1$ terraform apply
terraform管理下のリソースすべて消去する
1$ terraform destroy
リソースの閲覧
1$ terraform show
既存環境 import
※terraform varsion1.5から下記手順とは異なる方法でインポートできるようになりました
インポート手順 lambdaの例
必要最低限のtfファイルを作る
1resource "aws_lambda_function" "cognito_login" { 2}
Webコンソールで作成したリソースをimport
terraform import 取り込みたいサービス名.インポートしたい名前 AWSにあるリソース のような形で実行します lambdaの例だと下記のようになります
1$ terraform import aws_lambda_function.<インポートしたい名前> <すでにAWS上で作成されているLambda関数名>
インポートする際の注意点
一点注意して頂きたいのはリソースごとにインポートコマンドの書き方が異なります。 先ほどのlambdaの場合はコマンドの末尾にlambda関数の名前を入力していましたが、 例えばEC2インスタンスの場合は、以下のようにコマンドの末尾にはインスタンスのidを入力します<br>
1$ terraform import aws_instance.web i-12345678
参照:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#import <br> インポートのコマンドはリソースごとに調べて実行しましょう
import後にterraform state list
コマンドで取り込んだリソースの名前を取得し、terraform state show
コマンドでリソースの情報が見れる
1$ terraform state list 2 3aws_lambda_function.cognito_login 4 5$ terraform state show aws_lambda_function.cognito_login
1resource "aws_lambda_function" "cognito_login" { 2 architectures = [ 3 "x86_64", 4 ] 5 arn = "arn:aws:lambda:ap-northeast-1:************:function:cognito" 6 function_name = "cognito" 7 handler = "lambda_function.lambda_handler" 8 id = "cognito" 9 invoke_arn = "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:************:function:cognito/invocations" 10 last_modified = "2025-11-09T00:00:00.000+0000" 11 layers = [] 12 memory_size = 128 13 package_type = "Zip" 14 qualified_arn = "arn:aws:lambda:ap-northeast-1:************:function:cognito:$LATEST" 15 reserved_concurrent_executions = -1 16 role = "arn:aws:iam::************:role/service-role/cognito-role-n44l3fff" 17 runtime = "python3.9" 18 source_code_hash = "qUoU5sSYPTtEdpRr456MYKgW4MOCSaedddKZj0ebKLkk=" 19 source_code_size = 2000 20 tags = {} 21 tags_all = {} 22 timeout = 3 23 version = "$LATEST" 24 25 timeouts {} 26 27 tracing_config { 28 mode = "PassThrough" 29 } 30} 31
こちらを上記の.tfファイルにコピペし、いらない箇所や環境によるものの値を修正していく
修正が終わったらterraform plan
を実行し、No changes.
と出れば差分なくインポート完了です
Git BashでTerraform importしたときにパスが勝手に変換されてエラーになる場合の対処法
windowsのgitbashで作業していたら遭遇したバグ
tfstateについて
terraformには状態管理のためのtfstateというファイルがあります。 ローカルで管理するか、S3などのウェブ上で管理するか選べます。 下記の設定はローカルで保存。
1terraform { 2 backend "local" { 3 path = "./terraform.tfstate" 4 } 5}
s3保存にする場合の例 事前にs3バケットを作成する必要あり
1terraform { 2 backend "s3" { 3 bucket = "test-terraform-tfstate" 4 region = "ap-northeast-1" 5 key = "terraform.tfstate" 6 encrypt = false 7 shared_credentials_file = "$HOME/.aws/credentials" 8 } 9}
s3バケット作成と同時にローカルのファイルアップロード
s3にバケット作成と同時にファイルアップロードをしたい時があります 下記のように書けます
1resource "aws_s3_bucket" "aws_s3_bucket" { 2 bucket = "test_aws_s3_bucket" 3 object_lock_enabled = false 4 tags = {} 5 tags_all = {} 6 force_destroy = null 7} 8 9resource "aws_s3_object" "test_file_upload" { 10 bucket = aws_s3_bucket.aws_s3_bucket.bucket_name 11 key = "test.json" 12 source = "./test.json" 13}
リソースを作るかどうかを動的に制御したい
countを使ってtrue,falseの条件式が書けます
下記はapigatawayのリソースポリシーをつけるか付けないかの例
var.api_gateway_is_resource_policy
の値がtrue
ならこのリソースは作られることになります
1resource "aws_api_gateway_rest_api_policy" "api_policy" { 2 count = var.api_gateway_is_resource_policy ? 1 : 0 3 4 rest_api_id = aws_api_gateway_rest_api.test_api.id 5 policy = jsonencode({ 6 Statement = [ 7 { 8 Action = "execute-api:Invoke" 9 Condition = { 10 NotIpAddress = { 11 "aws:SourceIp" = [for ip in var.ip_list : ip] 12 } 13 } 14 Effect = "Deny" 15 Principal = "*" 16 Resource = "arn:aws:execute-api:*:*:*" 17 }, 18 { 19 Action = "execute-api:Invoke" 20 Effect = "Allow" 21 Principal = "*" 22 Resource = "arn:aws:execute-api:*:*:*" 23 }, 24 ] 25 Version = "2012-10-17" 26 }) 27}
terraformで管理したくないけどリソースの情報が欲しい
importしてしまうと削除時に一緒に消えちゃってまずいとかのリソースを情報だけ引っ張りたい時に使います
下記の場合importしていない為、terraform destroy
コマンドを実行してもroute53のリソースは消えません
1data "aws_route53_zone" "host_domain" { 2 name = var.domain_name 3} 4 5resource "aws_route53_record" "test_record" { 6 name = var.sub_domain_name 7 type = "A" 8 9 # ↓ 下記のような形でimportを行わなくても情報の参照ができる 10 zone_id = data.aws_route53_zone.host_domain.zone_id 11 alias { 12 name = aws_api_gateway_domain_name.api_gateway_domain_name.regional_domain_name 13 zone_id = aws_api_gateway_domain_name.api_gateway_domain_name.regional_zone_id 14 evaluate_target_health = true 15 } 16}
依存関係を明示的に指定したい
あるリソースの方が先に作って欲しい時に使用します depends_onにリソースを書いておきます
1resource "aws_api_gateway_deployment" "test_api_deployment" { 2 depends_on = [ 3 module.lambda_login 4 ] 5 rest_api_id = aws_api_gateway_rest_api.test_api.id 6 triggers = { 7 redeployment = filebase64("./api-gateway.tf") 8 } 9}