NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    【AWS】Terraform導入時に考えておきたい4つのこと

    はじめに

    こんにちは。加藤です。

    今回はAWS環境におけるTerraformの導入時に考えておきたいポイントを4つ紹介しようと思います。

    あくまで私個人の見解ですので、参考程度に見ていただければ幸いです。

    スコープ

    本記事ではAWSやTerraformの基本知識については割愛いたします。また、AWSとGoogleCloud、TerraformとCDKなどの類似サービスやツールの比較も行いません。

    AWS案件でTerraform導入を検討しているが、何をどう決めていけば良いか迷っている、という方に、まずは最小限考えおきたい点として書き残していければと思います。

    構成例

    まずは最終的なゴールをイメージしておきましょう。

    Terraform導入後の構成図の一例を載せておきますので、どういった要素があるかを頭に思い浮かべつつ読み進めていただければ良いかと思います。

    ここでは、以下4つのポイントに焦点を当てて関連項目を紹介したいと思います。

    1. ソースコード管理ツール
      • 図ではGitHubとしています。
    2. 実行基盤
      • GitHub ActionsやHCP Terraformと捉えていただければ良いです。
    3. 認証とアクセス経路
      • ここではOIDCを紹介します。
    4. ステート管理
      • Terraformで重要な構成要素であるStateの管理方法です。

    Point 1:ソースコード管理ツール

    まずはソースコード管理ツールです。

    Terraformの設定ファイル(.tfファイル)を格納するために必要な管理ツールを選定します。

    代表的なツールとして、GitHubGitLabBitBucketなどがあります。料金プランや各機能を比較したり、組織の方針に則り検討を進める形になるかと思います。

    ツールの選定時はTerraformの開発フローをどうするのか、と言う点も重要です。ここで言う開発フローとは、①実装 -> ②検証 -> ③レビュー -> ④リリース といったTerraformコードを運用する一連の流れのことを指します。

    開発フローについて、具体的な検討事項例を見ていきましょう。

    ブランチ戦略

    ブランチ戦略は開発フローの検討事項の一つです。Git-flowが有名かと思います。

    アプリケーションコードでは環境毎にブランチを分割することも多いように思えますが、Terraformではディレクト分割やWorkspaces機能で環境を区分することが可能であるため、ブランチベースの厳密な環境分離の運用を敷かなくてもある程度制御できるように思えます。実際、私が関わった案件ではシンプルさを考慮して mainブランチとfeatureブランチのみとしていることが多かったです。

    Terraformのブランチ戦略については以下のドキュメントでも言及されているので、参考にしてみてください。

    cloud.google.com

    PRマージ条件

    ブランチ戦略と関連してですが、Pull Request(PR)のマージ条件も検討しておきたいです。適切なPRマージ条件を設定することで、意図しないコードの変更を防ぎ事故防止に繋がります。(無論、mainブランチへの直接Pushは禁止しておきましょう。)

    例えば、「特定メンバーの承認が必要」や「二人以上のチームメンバーの承認が必要」などのマージ条件を設けることを想定します。GitHubではブランチ保護ルールによってきめ細やかにPRのマージ条件が設定可能です。

    実現したい条件が機能として備わっているか、ツール選定時にはチェックするようにしましょう。

    唐突の宣伝ですが、少し前にPRレビューについての記事を書いたので、ご興味あれば読んでみてください。

    tech.nri-net.com

    静的チェック

    Terraform導入時は静的チェックツールは入れるようにしましょう。Terraformではtflintが一般的かと思います。

    静的チェックツールを導入することでコードのフォーマットを統制し、不適切な設定を自動で検知出来ます。つまり、コードの品質担保に直結します。

    軽視されがちな気がしていますが、例えば初期構築メンバーと運用メンバーが異なる場合、運用メンバーがコードを変更しようとした時にコードのフォーマットが他とは違ったりすると、何故そうなっているか、差異に意図があるのではないか、と考えてしまいます。ここの検討コストは馬鹿に出来ません。しかも、蓋を開けると初期メンバーの気分だった、と言うことは「あるある」かと思います。

    そのようなことを防ぐため機械的にコードを統制し、人の意思を極力排除したコードを保守できるようにしましょう。

    静的チェックは、pre-commitMegaLinterを利用することで自動的に実行されるようにしておくことが望ましいです。メンバーのPC端末に依存する仕組みは極力避けましょう。

    Point 2:実行基盤

    開発フローが整理されソースコード管理ツールが決まれば、続いてTerraformの実行基盤を考えていきましょう。

    実行基盤を考える上で、まずはチーム開発の課題について簡単に触れておきます。

    例えば、個人開発であればPC端末にTerraformをインストールしTerraformコマンドを実行すれば十分です。しかし、チームで開発する場合、Terraformの実行基盤をPC端末に限定してしまうと、いくつかイヤなことが起きます。

    • コマンド結果がPC端末の状態に依存する
      • 当たり前ですがOSや各種ツールのバージョンなどでコマンド結果が変わってしまうことがあります。
    • PC端末から直接AWS環境が叩けてしまう
      • 後述しますが、アクセス経路を考えた時に個人のPC端末から直接AWS環境が触れる状況はリスクがあります。特に強い権限を付与している場合は事故が起きないように注意が必要でしょう。
    • コマンドの実行結果の信憑性が下がる
      • 最近はテレワーク中心の方も多いかと思いますが、その場合はコマンドの実行結果(主にPlan結果)の連携もチャットツールなどで行うことになります。その場合コピペミスや別のブランチで実行していたなどヒューマンエラーが入り込む余地が出来てしまい、コマンドの実行結果の信憑性が下がってしまいます。
    • 細かいルール作りによる運用負荷の向上
      • PCセットアップドキュメントの保守運用も大変です。

    この辺りの懸念を排除するために、Terraformを実行する共通の実行基盤を準備し、そこでTerraformコマンドを叩く運用としておくことが望ましいと考えています。とはいえ、検証段階では手っ取り早くPC端末からTerraformコマンドを実行したい、と言うことも運用上多いので、本番環境などリスクが高い環境に対しては共通の実行基盤を用いて開発環境などはPC端末からの実行を許可する、という運用としても良いでしょう。

    前置きが長くなりましたが、具体的な共通な実行基盤の選択肢として、踏み台サーバ、GitHub ActionsAtlantisHCP Terraformなどが考えられます。

    Atlantisはソースコード管理ツールと連携してPR上でTerraformコマンドを実行することが可能なツールです。実態は裏でAtlantisを実行するホストを立てて、そことソースコード管理ツールを連携させるイメージです。PR上でコマンドを実行することにより、開発フローに組み込みやすいです。またロック機能があるため競合も防ぐことが出来ます。

    HCP TerraformはHashiCorp(Terrafromの開発元)が提供するTerraform管理をクラウド上で行えるツールです。最近、HCP Terraformを触る機会があったのですが、Remote operationsが非常に良い機能だなと思いました。その理由としては、PC端末での作業に慣れているメンバーの開発者体験を変えることなくHCP Terraformを利用することが出来る、と言う点です。細かい挙動はリンク先を確認いただければですが、この点は別の実行基盤からの移行を検討している場合は大きなアドバンテージになるのではないかと考えています。

    ディレクトリ構成

    ディレクトリ構成についても検討が必要です。まず簡単なディレクトリ構成を示します。

    ├── envs
    │   ├── dev
    │   │   ├── backend.tf
    │   │   ├── local.tf
    │   │   ├── main.tf
    │   │   ├── output.tf
    │   │   ├── providers.tf
    │   │   └── versions.tf
    │   └── prod
    │       ├── backend.tf
    │       ├── local.tf
    │       ├── main.tf
    │       ├── output.tf
    │       ├── providers.tf
    │       └── versions.tf
    └── modules
        ├── ecs
        │   ├── main.tf
        │   └── variables.tf
        └── network
            ├── main.tf
            └── variables.tf

    devprodの2つの環境を対象にECSを用いたシステムを構築するイメージです。

    ポイントは以下の通りです。

    • 環境毎にディレクトリを分割する
      • 直感的で分かりやすいコード体系として事故を軽減します。
      • Terraformの実行は各環境ディレクトリで実行します。上の例では、envs/devenvs/prodです。
    • 共通部分はパーツ化して集約
      • コードをDRYに保つように心がけましょう。
      • モジュールの分割粒度はリリースライフサイクルによって分割しています。

    ディレクトリ構成は、かなり奥が深いのでページ下部のベストプラクティスを参考にいただくのが良いかと思います。実際に運用してみないと気づきにくいポイントではあるのですが、システム規模などを考慮してある程度柔軟な構成としておくのが無難であるように思えます。

    更に言うとTerraformコードのディレクトリをMono RepoとするかMulti Repoとするか、と言う点も検討出来ます。関わった案件はMono Repoが多いですが、それぞれメリット・デメリットはあります。詳細は以下リンクをご確認ください。

    www.hashicorp.com

    バージョン管理

    Terraform運用において管理対象のバージョンを見ておきましょう。

    まずはTerraform本体です。リリース履歴は以下から確認できます。2025年3月10日時点では v1.11.1 が最新ですね。

    github.com

    各プロバイダーバージョンも気にかけておきましょう。具体的にはAWS Providerなどです。リリース履歴は以下から確認できます。

    github.com

    それら以外にもTerraformで利用するツール(tflint等)やパブリックモジュール(AWS VPC Terraform module等)のバージョンなども気にかけておきましょう。

    バージョン更新は人力ではなく自動更新に任せたいところです。GitHubではDependabotRenovateなど自動更新ツールがありますので、各ツールが活用出来ないか検討しても良さそうです。

    Point 3:認証とアクセス経路

    次に認証とアクセス経路です。

    実行基盤→AWS環境へのアクセス経路を検討しておきましょう。

    まず認証ですが、AWSだとOpenID Connect(OIDC)連携が便利です。事前にIdPと信頼関係を結んでおくことで、AWSから一時的な認証情報(STS)を取得してアクセスが可能となります。IAMユーザのアクセスキーやシークレットキーの管理から解放され、かつセキュリティ向上にもつながります。

    GitHub ActionsやHCP TerraformでもOIDC連携がサポートされています。

    docs.github.com

    www.hashicorp.com

    共通の実行基盤からのアクセスはOIDC連携で良さそうですが、前述した通り、PC端末→AWS環境へアクセスする場合はPC端末で設定したAWS認証情報からのAssumeRoleを許可したIAMロールを用意して利用する形になるかと思います。

    PC端末→AWS環境へのアクセスの際に強い権限を与えてしまうと思わぬ事故につながるので、通常は読み取り専用のIAMロールを使用して必要に応じて書き込み用のIAMロールに切り替える、と言う運用としても良いでしょう。具体的には、.tfvarsファイルで書き込み用のIAMロールを定義しておき、terraformコマンド実行時に-var-fileで読み込みAssumeRole先のIAMロールを上書くことで切り替えることが可能です。

    合わせて、実行基盤(or PC端末)→Stateへのアクセス経路も確認しておきましょう。

    後述しますが、StateはS3バケットなどで管理することが望ましいです。その場合、Stateを管理している箇所への認証も考えておく必要があります。先程、AWS環境の実リソースにアクセスした際に利用したIAMロールと同じで良いように思えますが、Stateへのアクセスは別のIAMロールを指定することが可能です。具体的にはbackendブロックのassume_roleで指定します。

    backend.tf

    terraform {
      backend "s3" {
        bucket = "t3-kato-terraform-backend"
        key    = "key_path"
        assume_role = {
          role_arn     = "arn:aws:iam::XXXXXXXXXXXX:role/Terraform_ro" ← ここ
        }
        region = "us-east-1"
      }
    }
    

    Stateと実リソースへのアクセスで用いる認証情報を分離出来ることにより、例えばStateをAアカウントのAWSアカウントに置いているが、実リソースはBアカウントにある、というような状況でも柔軟に認証情報を使い分けることも可能です。

    Point 4:State管理

    最後にState管理についてです。

    前章でも少し触れましたが、StateはTerraformの状態を管理しておくファイルです。コードと実リソース間で情報をマッピングする役割を担います。

    チームでTerraformを運用する場合は、S3バケットのようなリモートにおくことが望ましいです。例えば、リモートではなくLocalでStateを管理している場合、PC端末→AWS環境にterraform applyを実行した場合にLocalのState情報が更新されます。この後、別のメンバーが別のブランチでterraform planを叩くとPC端末のState情報と実リソースが乖離しており、正しい結果とならない可能性があります。

    このような事態を防ぐためにStateは誰がどこでコマンドを実行しても単一のファイルを参照するように設定しておきましょう。

    補足

    ここまでTerraformを導入する際に考えておきたいことを4つ紹介しました。

    もちろん今回紹介した内容以外にも考慮点はあります。

    補足としてTerraformのベストプラクティスと各種ツールを紹介しておきます。

    ベストプラクティス

    spacelift.io

    cloud.google.com

    Terraform導入前には、こちらを一読することをお勧めします。

    ベストプラクティスは全ての事項について厳守していくのではなく、案件の特性やメンバーのスキルセット等を考慮し必要に応じて利用する形が望ましいと考えています。重要なのは運用を品質高く維持できるか、という点だと思いますので要件とすり合わせつつ無理のない設計としておくのが良いかと思います。

    AWSからもTerraformのベストプラクティスが公開されているので、合わせてチェックしておきましょう。

    docs.aws.amazon.com

    各種ツール

    途中紹介したtflintなどの他にTerraformでは便利なツールが複数開発されています。

    github.com

    必要に応じて導入を検討しましょう。

    さいごに

    Terraformは便利なツールではありますが、その分特性を把握して適切に運用する力が求められます。まずは全体像を掴んで、その後各構成について役割や意図を理解していくように心がけましょう。

    本記事がどなたかの参考になれば幸いです。

    執筆者: 加藤 俊稀

    🧑‍💻クラウドエンジニア / インフラエンジニア
    🎖️ 2025 Japan All AWS Certifications Engineers
    📝https://tech.nri-net.com/archive/author/t3-kato