Skip to content

Terraform インフラストラクチャ

Terraform は、インフラストラクチャを安全かつ予測可能に作成、変更、改善できるオープンソースの Infrastructure as Code ソフトウェアツールです。

Terraform インフラストラクチャジェネレーターは、Terraform インフラストラクチャプロジェクトを作成します。生成されたアプリケーションには、Checkov セキュリティチェックによるセキュリティのベストプラクティスが含まれています。

新しい Terraform プロジェクトは 2 つの方法で生成できます:

このジェネレーターを実行@aws/nx-plugin:terraform#project

pnpm nx g @aws/nx-plugin:terraform#project
コマンドを組み立てる5

必須

ジェネレーターオプション5 オプション
name必須string

プロジェクトの名前。

typeenumデフォルト: application

これがterraform lib(再利用可能なモジュール)かapp(デプロイ可能)かを指定します。

applicationlibrary
directorystringデフォルト: packages

新しいプロジェクトのディレクトリ。

subDirectorystring

プロジェクトが配置されるサブディレクトリ。デフォルトではプロジェクト名になります。

preferInstallDependenciesbooleanデフォルト: true

ジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合はfalseに設定します(後続のジェネレーターがNxプロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

ジェネレーターは、プロジェクトタイプに応じて異なるファイル構造を作成します:

type = application

アプリケーションプロジェクト(--type=application)の場合、ジェネレーターはリモート状態管理を備えた完全な Terraform アプリケーションを作成します:

  • Directorysrc
    • main.tf Main Terraform configuration file
    • providers.tf Provider configuration with S3 backend
    • variables.tf Input variable definitions
    • outputs.tf Output value definitions
    • Directoryenv Environment-specific variable files
      • dev.tfvars Development environment variables
  • Directorybootstrap Bootstrap configuration for remote state
    • main.tf S3 bucket and policies for state storage
    • providers.tf AWS provider configuration
    • variables.tf Bootstrap variable definitions
  • Directoryscripts Node helpers run by the nx bootstrap, bootstrap-destroy and init targets
    • aws-config.ts Resolves account + region via the AWS SDK credential chain
    • bootstrap.ts Pulls/pushes the bootstrap tfstate and runs terraform apply
    • bootstrap-destroy.ts Empties the state bucket and runs terraform destroy
    • init.ts Runs terraform init with the S3 backend config
    • env.ts Points terraform init at the shared provider cache
  • checkov.yml Checkov configuration, including the checks to skip
  • project.json Project configuration and build targets
type = library

ライブラリプロジェクト(--type=library)の場合、ジェネレーターは再利用可能な Terraform モジュール用のよりシンプルな構造を作成します:

  • Directorysrc
    • main.tf Main Terraform module file
  • checkov.yml Checkov configuration, including the checks to skip
  • project.json Project configuration and build targets

Terraform インフラストラクチャの実装

Section titled “Terraform インフラストラクチャの実装”

src/main.tf 内で Terraform インフラストラクチャの記述を開始できます。例えば:

src/main.tf
locals {
account_id = data.aws_caller_identity.current.account_id
aws_region = data.aws_region.current.id
}
resource "null_resource" "print_info" {
# triggers = {
# always_run = timestamp()
# }
provisioner "local-exec" {
command = "echo 'AWS Region: ${local.aws_region}, AWS Account: ${local.account_id}, Environment: ${var.environment}'"
}
}
# Declare your infrastructure here
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
}

上記の S3 バケットは、バケットに適切なセキュリティ設定が有効になっているかをチェックする Checkov セキュリティスキャンに失敗することに注意してください。

別のプロジェクト(lib)からモジュールを実行したい場合は、次のようにできます:

module "lib_module" {
source = "../../path/to/my-lib/src"
}

これにより、Nx グラフが自動的に更新され、使用するアプリケーションとライブラリの間に依存関係が追加されます。

src/env/*.tfvars ファイルで環境固有の変数を設定します。

新しい環境を追加するには、環境固有の変数を含む新しい src/env/<environment>.tfvars ファイルを作成し、新しい環境設定用に project.jsonapply, destroy, init, plan に新しいエントリを追加します。例えば、prod 環境を追加したいとします:

# Production environment variables
environment = "prod"
aws_region = "us-west-2"
type = application

リモート状態のブートストラップ(アプリケーションプロジェクトのみ)

Section titled “リモート状態のブートストラップ(アプリケーションプロジェクトのみ)”

インフラストラクチャをデプロイする前に、リモート状態バックエンドをブートストラップする必要があります。これにより、Terraform 状態ファイルを保存する S3 バケットが作成されます:

Terminal window
pnpm nx bootstrap tf-infra

利用可能なターゲットは、プロジェクトタイプによって異なります:

共通ターゲット(アプリケーションとライブラリの両方)

Section titled “共通ターゲット(アプリケーションとライブラリの両方)”

validate ターゲットを使用して Terraform 設定を検証できます:

Terminal window
pnpm nx validate tf-infra

Terraform プロジェクトは terraform fmt を使用してフォーマットをチェックします。

プロジェクトをチェックするためにリンターを呼び出すには、lint ターゲットを実行します。

Terminal window
pnpm nx lint tf-infra

リンティングやフォーマットの問題の大部分は、--configuration=fix 引数を付けて実行することで自動的に修正できます。

Terminal window
pnpm nx lint tf-infra --configuration=fix

同様に、ワークスペース内のすべてのパッケージのすべてのリント問題を修正したい場合は、次を実行できます:

Terminal window
pnpm nx run-many --target lint --all --configuration=fix

開発中にリンティング問題によって遅延するのを避けるため(特にプロジェクトに自動修正できない問題がある場合)、skip-lint 設定でビルドを実行できます:

Terminal window
pnpm nx run-many --target build --configuration=skip-lint

これにより、ビルド中のフォーマットチェックが完全にスキップされます。

checkov ターゲットで Checkov を使用してインフラストラクチャのセキュリティチェックを実行します:

Terminal window
pnpm nx checkov tf-infra

セキュリティテストの結果は、ルートの dist フォルダー内の dist/packages/<my-terraform-project>/checkov にあります。

Checkov は build の一部として実行されます。

チェックはプロジェクトの checkov.yml で設定されます。プロジェクト全体でチェックを抑制するには、skip-check にチェック ID を追加します:

checkov.yml
skip-check:
- CKV_AWS_115 # Concurrent execution limit
- CKV_AWS_116 # Dead Letter Queue

単一のリソースに対してのみチェックを抑制するには、リソースブロック内に #checkov:skip=<id>:<reason> コメントを追加します:

resource "aws_s3_bucket" "example" {
#checkov:skip=CKV_AWS_18:Access logging not required for this bucket
bucket = "example"
}

test ターゲットは、プロジェクト内の .tftest.hcl ファイルに対して Terraform のネイティブテストフレームワークを実行します:

Terminal window
pnpm nx test tf-infra

テストファイルがないプロジェクトは成功として扱われるため、必要なときにテストを追加できます。build はこのターゲットを実行するため、通常のビルドの一部としてテストが実行されます。

run ブロックは設定を評価します。command = plan を使用すると、Terraform が何を_行うか_を確認できます(これはモジュールグラフ全体を展開するため、validate では検出できない計画時のエラーをキャッチします)。また、command = apply を使用すると、実際のリソースを作成してその出力をアサートできます。mock_provider を宣言すると、API 呼び出しが行われず、AWS 認証情報も不要になるため、plan テストを高速かつ安全に CI で実行できます:

src/main.tftest.hcl
mock_provider "aws" {
mock_data "aws_caller_identity" {
defaults = { account_id = "123456789012" }
}
mock_data "aws_region" {
defaults = { region = "us-east-1" }
}
}
variables {
aws_region = "us-east-1"
environment = "dev"
}
run "plan_is_valid" {
command = plan
assert {
condition = data.aws_caller_identity.current.account_id == "123456789012"
error_message = "Unexpected account id"
}
}

設定に必要なすべての変数を variables ブロックに設定してください。そうしないと、「has a required variable … with no set value」というエラーで実行が失敗します。

terraform init を実行するすべてのターゲットは、ワークスペースルートの .terraform/plugin-cache にあるプロバイダーキャッシュを再利用するため、プロバイダーは毎回ではなく一度だけダウンロードされます。各プロジェクトはそこに独自のディレクトリを持ちます:2つの terraform init 実行が同時に1つのキャッシュを埋める場合、それぞれが同じプロバイダーに対して異なるハッシュを計算する可能性があり、terraform はそれを .terraform.lock.hcl に対して拒否します。詳細については、Terraform ドキュメントを参照してください。

環境で TF_PLUGIN_CACHE_DIR を設定して、提供される init スクリプトを自分で管理するキャッシュ(たとえば、ワークスペース間で共有されるボリューム)に向けることができます。test ターゲットは project.json からパスを読み取るため、そこでも変更してください。

type = application

アプリケーション専用ターゲット

Section titled “アプリケーション専用ターゲット”

以下のターゲットは、アプリケーションタイプのプロジェクトでのみ使用できます:

変更を適用する前に、plan ターゲットを実行して Terraform が何を行うかを確認できます:

Terminal window
pnpm nx plan tf-infra

これにより、dist/packages/<my-terraform-project>/terraform/dev.tfplan にプランファイルが作成されます。

planassemble に依存しているため、lint、test、type-check ゲートを実行せずに、Lambda バンドルや生成された操作メタデータなど、モジュールが参照するアーティファクトを生成します。

init ターゲットで Terraform 作業ディレクトリを初期化します:

Terminal window
pnpm nx run tf-infra:init

計画後、apply ターゲットを使用してインフラストラクチャを AWS にデプロイできます:

Terminal window
pnpm nx apply tf-infra

Terraform 設定から出力値を取得します:

Terminal window
pnpm nx output tf-infra

インフラストラクチャを削除する必要がある場合は、destroy ターゲットを使用します:

Terminal window
pnpm nx destroy tf-infra

ブートストラップリソースの破棄

Section titled “ブートストラップリソースの破棄”

ブートストラップリソース(状態保存用の S3 バケット)をクリーンアップするには:

Terminal window
pnpm nx bootstrap-destroy tf-infra

これは、バケットを破棄する前に状態バケットを空にし、AWS SDK 認証情報チェーンからリージョンを解決するため、CI で無人実行できます。

Terraform の詳細については、Terraform ドキュメントおよび AWS プロバイダードキュメントを参照してください。