2025/09 技術インプットまとめ

日報




エンジニアとして日々新しい知識をインプットしています。現在の職場には、毎日の終業時に日報を提出する文化があり、その中に「本日発見したこと・気づいたこと」を記載する欄が設けられています。私はこの欄を、業務で得た新しい知見や、業務外の自己学習で学んだことを記録するアウトププットの場として活用しています。この記事は、その日々の学びを知識として定着させ、いつでも振り返れる資産にするために、1ヶ月分をまとめたものです。

2025-9-1

terraform plan の内部的な挙動について理解することができました。

1、State をバックエンド(S3)から一時的な作業用メモリ上に読み込む(ここではまだ S3 上の tfstate を読むだけ)

2、既定では in-memory refresh(メモリ上のリフレッシュ)を行う(-refresh=false なら省略)
・各リソースの実体(AWS)の最新状態をプロバイダ経由で取得し、メモリ上の作業用ステートを最新化する(出力に Refreshing state… が出るやつ)
・※ この時点では S3 の state ファイル自体は書き換えない

3、その「リフレッシュ済みのメモリ上ステート」と「ローカルの .tf」を突き合わせ、差分(Plan)を作る
・ここまでが plan。S3 の state を更新するのは apply を承認したときだけ

2025-9-2

terraform plan 時に、リモートバックエンドから一時的な作業用メモリに読み込んだ .tfstateの中身を、実環境のリソース状態で上書き(リフレッシュ)する理由を知ることができました。

常に「Terraform だけで運用しているから state は最新のはず」という前提でも、手動変更, 外部オートメーション, プロバイダの計算属性(例:タイムスタンプ/ID/エンドポイントの実値), 非同期更新などでドリフトが起き得る。Plan 前に実体を読み直すのは、意図せぬズレを先に見つけるための安全策という位置づけ。

2025-9-3

*.tfplan(計画ファイル)を Git で無視するべき理由について知ることができました。

・バイナリで、Terraform/OS/プロバイダのバージョン依存 → 可搬性が低い
・都度変化し、場合によっては機微も含み得る
・監査したいなら、CI のアーティファクトやPRコメントの plan 出力で残すのが一般的
・例外として「必ず plan → apply(plan)」という厳格プロセスでも、保存先はGit ではなく CI のストレージが無難

2025-9-5

Terraform の state を1枚にするか、分割するかという将来設計について迷いがあったので、ベストプラクティスを調べました。下記を知ることができました。

結論:最初は「環境 × 1枚」から始め、痛みが出たら「領域ごとに 2〜4枚へ分割」がバランス良い

比較
1枚(例:staging/global.tfstate)
・メリット:シンプル、依存解決が楽(同一 state 内の参照は自然に依存関係に)
・デメリット:plan/apply が重くなる、ロック競合でチーム並行作業が詰まりやすい

分割(例:staging/network.tfstate, staging/platform.tfstate, staging/app.tfstate)
・メリット:ロックが独立 → 並行作業に強い/故障半径が小さい/権限境界を分けやすい
・デメリット:跨ぎ参照は data “terraform_remote_state” 等が必要 → 依存の明示・順序管理が増える

目安:所有チームやライフサイクルが異なる単位で分割。典型は
・network(VPC, Subnets, IGW/NAT, RouteTables, TGW)
・platform(ECR, KMS, ALB共通, Observability, SSM, IAM共通 等)
・app(ECS/EKS/EC2, RDS/ElastiCache 等のワークロード)
= 2〜4枚/環境 が多い

2025-9-8

X-Forwarded-For(XFF)ヘッダーについて知ることができました。

・XFFヘッダーは、プロキシやロードバランサを経由したリクエストでも、元のクライアントIPアドレスをアプリ側に伝えるための事実上の標準ヘッダー
・値はカンマ区切りのIPの列で、通常 左端が元のクライアント、右に行くほど後段のプロキシになる
・ヘッダーはなりすまし可能のため、信頼できる中継だけを「trusted proxies」として扱うのが基本

2025-9-9

jqコマンドについて知ることができました。

jqコマンドとは、JSONから簡単に値を抜き出したり、集計したり、整形して表示したりできるJSON用のgrepとかawkみたいなコマンド。WebサービスがJSONを吐いたり、AWS CLIが JSON を吐いたりする現代社会で大変便利なコマンド。

2025-9-10

Terraformにおいて、state分割を行う際の全体的な手順について知ることができました。

全体像(順序)
1. 変更フリーズ(main も apply もしない)/plan が差分0であることを確認
2. 分割境界を決める(例:network と app)
3. 新ルートを作る(例:environments/staging/network/)+ 新state key を用意(staging/network.tfstate)
4. 対象リソースを新ルートに移す
    ・A: 再インポート方式(推奨)
    ・B: state を“オフラインで”移送(上級者向け)
5. 旧ルートからそのリソースを外す(HCL削除 or state rm)
6. 跨ぎ参照は terraform_remote_state へ置き換え
7. 両ルートで plan が差分0になることを確認 → 解除

2025-9-11

state分割を行うにあたり、対象リソースを新ルートに移す1つの方法である「再インポート方式」について知見を得ることができました。

・ポイント:クラウド上の実体は動かさず、新ルートの state に「紐付け直す」だけ
・旧ルートでは apply しない(競合を避ける)

1. 新ルートに HCL を用意(移すリソースだけ)
    ・既存 HCL をコピペでも、まずは空でもOK(import + -generate-config-outで生成可)

2. import ブロックを書いて取り込む
# environments/staging/network/imports.tf
import {
    to = aws_vpc.main
    id = vpc-0abc1234def567890
}
import {
    to = aws_subnet.public_a
    id = subnet-0123abcd4567efgh
}
# …必要分だけ

3. 生成&取り込み
terraform plan -generate-config-out=generated.tf
terraform apply

・これで 新state(staging/network.tfstate)に紐付く
・generated.tf を vpc.tf などに整理 → imports.tf は不要になれば削除

4. 旧ルートから外す
・旧ルートで、そのリソースの HCLを削除(または一時コメントアウト)
・念のため 追跡も外す場合は、旧ルートで
    terraform state rm aws_vpc.main
    terraform state rm aws_subnet.public_a
・旧ルートで terraform plan → 対象が消える差分が出ない(=もともと HCL も無い)ことを確認。(HCLを先に消さず state だけ外すと「削除(destroy)」が提案されるので順序に注意)

これで「新:管理中」「旧:非管理」へ切り替わる。取り込み → 即座に旧の HCL/state を外す、で二重管理の時間を極小化できる。

2025-9-12

state分割を行うにあたり、対象リソースを新ルートに移す1つの方法である「stateをオフラインで移送する方法」について知見を得ることができました。

リモートstateを一度ローカルへ pullして、state mv -state/-state-outで別stateへ移動 → pushする方法

1. 旧・新それぞれで state をローカルに保存
# 旧ルート
terraform state pull > /tmp/src.tfstate
# 新ルート
terraform state pull > /tmp/dst.tfstate

2. アドレスを移動
terraform state mv \
    -state=/tmp/src.tfstate \
    -state-out=/tmp/dst.tfstate \
    ‘aws_vpc.main’ ‘aws_vpc.main’
# 他のリソースも同様に

3. 各backendsへpush
# 旧ルート(削除後のsrcを反映)
terraform state push /tmp/src.tfstate
# 新ルート(追加後のdstを反映)
terraform state push /tmp/dst.tfstate

失敗時に戻せるよう、push 前に /tmp のバックアップを必ず取っておくこと。この方法は手順ミスの余地があるため、まずは 再インポート方式を推奨。

2025-9-16

Terraformにおいて、リソースアドレスの2つの変更方法を知ることができました。

① movedブロック(同一state内でのリネーム/移動用・推奨)
moved {
    from = aws_cloudwatch_log_group.app
    to = aws_cloudwatch_log_group.access
}
→ これで 実環境のリソースのdestroy/create を伴わずに Terraform が参照先を移してくれる

②:terraform state mv(手動で state のアドレスを移動)
terraform state mv aws_cloudwatch_log_group.app aws_cloudwatch_log_group.access

備考
・別 state への移動は moved は効かず、terraform state mv -state/-state-outか、再importが必要

2025-9-17

Terraformの同一state内において、movedブロックで「state上のアドレスだけ」を付け替える流れを知ることができました。

1. 新しい姿のコードにする
例:aws_cloudwatch_log_group.app を aws_cloudwatch_log_group.access にリネーム、
または モジュールへ移す(module.logging.aws_cloudwatch_log_group.access を定義し、旧リソース定義は削除)

2. moved ブロックを追加
・同じ state 内の 旧アドレス → 新アドレス を宣言する
・置き場所:両方のアドレスを参照できる最小の親モジュールに記述
    ・同一モジュール内のリネーム → そのモジュールに
    ・ルート → 子モジュール/子 → ルート → 親(ルート)モジュールに

3. terraform plan を確認
・期待値:moved from … to … が出て、Destroy/Create は出ない(= 実インフラに手を触れない)
・Destroy/Create が出るなら、moved の置き場所やアドレスが誤り

4. terraform apply
・state 内の参照先だけが更新され、AWS への API 呼び出しは発生しない
・以後、state 上のそのリソースは 新アドレスで管理される

5. moved の後始末
・すべての環境(staging→production)がこの変更を一度は適用し終えたら、moved を削除してもOK
・複数環境がバラバラに適用する期間は残しておくのが無難

2025-9-18

state を実環境に合わせて更新したいときの手順を知ることができました。

インフラを変えずに state だけ同期したい場合
・terraform plan -refresh-only → 差分確認 → terraform apply -refresh-only(承認して state を上書き)という refresh-only モードを使う
・terraform refresh サブコマンドより安全な推奨手段

2025-9-19

既存リソースをTerraform管理下へimportする際に、provider “aws” の default_tags により、タグが既存リソースに新規付与されますが(既存リソースにまだそのタグが付いていない場合)、このときにタグ付与は一旦行わず、純粋に import だけを行いたい(一旦は状態だけを取り込み、タグは後でまとめて付けたい)という場合の回避策を2つ知ることができました。

1、一時的に default_tags を無効化
・provider “aws” の default_tags {} をコメントアウトして plan/apply(importのみ)→ 後で戻す
・デメリット:後でタグ追加の差分が一気に出る

2、一時的に ignore_changes を付ける
生成されたリソースに
resource “aws_cloudwatch_log_group” “access” {
    # …
    tags = {}
    lifecycle { ignore_changes = [tags] }
}
で import。後日 ignore_changes を外してタグ追加を反映(注意:ignore は一時的な足場として使うのが吉)

とはいえ、タグ追加はリスク小さめなので、基本は今まとめて付けてしまう運用がおすすめ。

2025-9-22

Terraform の state に、今どんなリソースが登録(管理)されているかを確認するためのコマンドを知ることができました。

使いどころ:インポート済みかの確認や、既に Terraform 管理下に入っていないかの事前チェック

terraform state list
・現在のワークスペースの Stateファイルに記録されているリソースアドレス(例: aws_s3_bucket.logs, module.vpc.aws_subnet.public[0])を一覧表示する
・リモートバックエンド(例:S3)を使っている場合は、S3 の state オブジェクトにはアクセスをする。つまり S3 との疎通は必要
・ただし、AWS の各サービス API(EC2、S3 バケット本体、CloudWatch 等)に対して、「実リソースの現在の状態」を問い合わせたりはしない
・いわゆるリフレッシュ(実環境→state の同期)は行われない

よくある使い方 ①
terraform state list | grep -E ‘aws_s3_bucket.logs|aws_cloudwatch_log_group.app’
特定リソースだけを確認

よくある使い方 ②
terraform state list | sort
一覧を辞書順に整列して表示する。量が多いときに重複やモジュール配下(module.xxx. で始まるもの)を見つけやすくなる

2025-9-24

state に登録(管理)されているリソースの中身を詳しく確認するコマンドを知ることができました。
> terraform state show <リソースアドレス>

入力
$ terraform state show aws_cloudwatch_log_group.access

出力
# aws_cloudwatch_log_group.access:
resource “aws_cloudwatch_log_group” “access” {
    arn = “arn:aws:logs:ap-northeast-1:***:log-group:***-stg-access”
    id = “***-stg-access”
    kms_key_id = null
    log_group_class = “STANDARD”
    name = “***-stg-access”
    name_prefix = null
    retention_in_days = 0
    skip_destroy = false
    tags = {}
    tags_all = {
        “Environment” = “staging”
        “ManagedBy” = “Terraform”
    }
}

2025-9-25

terraform plan -out=planfile で出力されるplanfileは、Terraform本体/プロバイダのバージョンやOSに依存するバイナリで、他マシン間での互換性は保証されないことを知りました。

2025-9-26

terraform plan で出力される差分の詳細を見たいときの手順を知ることができました。

terraform plan -out=planfile
terraform show -no-color planfile | less

1つ目のコマンドで実行計画(planfile)を作成し、それを人間が読めるテキストに変換し、ページャで閲覧する
・terraform show planfile が計画内容(どのリソースを +作成 / ~変更 / -破棄 / -/+置換するか、属性の before→after など)を表示。未確定値は known after apply のように出る
・-no-color はANSIカラーコードを除去(ログ保存やパイプ用途に便利)
・| less でページングしながらスクロール/検索できる( /キーワード で検索、qで終了)。長行が折り返されて見づらいときは less -S も有用
・機械可読が必要なら terraform show -json planfile | jq のようにJSON出力にもできる

2025-9-29

terraform plan での差分確認の際の各記号の意味を知ることができました。

記号の意味
+ … 追加(新規作成、またはマップ/リストの要素追加)
– … 削除(リソース削除、または要素削除)
~ … 更新(in-place)(リソースを壊さずに属性だけ変える)
-/+ … 置き換え(destroy → create)(不可逆な属性変更などで作り直しが必要)

2025-9-30

Terraform における tags_all について知ることができました。

・tags_all とは、tags(明示)+ default_tags(providerで付与)の和集合を表す読み取り専用の計算属性