PR

第3章: Terraformの専門技術

第3章: Terraformの専門技術

7. モジュールの定義

TerraformのDRYな構築

Terraformでインフラストラクチャを管理する際、コードの重複を避け、再利用可能なコンポーネントを作成することは非常に重要です。これは「DRY(Don’t Repeat Yourself)」原則とも呼ばれ、Terraformではモジュールを使用して実現します。

モジュールを使用する主なメリットは以下の通りです:

  • コードの再利用性: 同じリソース構成を複数の環境で使用できる
  • 抽象化: 複雑なインフラを論理的なコンポーネントに分割できる
  • バージョン管理: モジュールにバージョンを付けて、安定した状態で共有できる
  • 一貫性: 組織全体で標準化されたインフラパターンを適用できる

例えば、標準的なVPC設定を複数のプロジェクトで再利用したい場合、以下のようなモジュール構造を作成できます:

modules/
  vpc/
    main.tf
    variables.tf
    outputs.tf
    README.md

main.tfではVPCリソースを定義し、variables.tfで設定可能なパラメータを定義します。outputs.tfでは、モジュールから出力する値(VPC ID、サブネットIDなど)を定義します。

module の使い方

モジュールを使用するには、以下の構文を使用します:

module "vpc" {
  source = "./modules/vpc"
  
  vpc_cidr       = "10.0.0.0/16"
  region         = "ap-northeast-1"
  environment    = "production"
}

モジュールのソースは以下のような様々な場所から指定できます:

  • ローカルパス: ./modules/vpc
  • GitHubリポジトリ: github.com/username/terraform-aws-vpc
  • Terraform Registry: terraform-aws-modules/vpc/aws

実践的な例として、AWSでのウェブアプリケーション用のモジュール構成を考えてみましょう:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.14.0"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a", "ap-northeast-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = true

  tags = {
    Environment = "production"
    Project     = "MyApp"
  }
}

module "web_server" {
  source = "./modules/web_server"
  
  vpc_id            = module.vpc.vpc_id
  subnet_ids        = module.vpc.private_subnets
  instance_type     = "t3.medium"
  environment       = "production"
}

このように、モジュールを組み合わせることで、複雑なインフラを論理的な単位に分解し、管理しやすくすることができます。

8. TerraformのCI/CD適用

GitHub ActionsでTerraformを自動適用

Terraformを継続的インテグレーション/継続的デプロイメント(CI/CD)パイプラインに統合することで、インフラ変更の自動化と品質保証が可能になります。GitHub Actionsは、このプロセスを簡単に設定できるツールの一つです。

GitHub Actionsでのワークフロー例:

name: "Terraform CI/CD"

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  terraform:
    name: "Terraform"
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.3.0
      
      - name: Terraform Format
        id: fmt
        run: terraform fmt -check
      
      - name: Terraform Init
        id: init
        run: terraform init
      
      - name: Terraform Validate
        id: validate
        run: terraform validate
      
      - name: Terraform Plan
        id: plan
        if: github.event_name == 'pull_request'
        run: terraform plan -no-color
        continue-on-error: true
      
      - name: Update Pull Request
        uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
            #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
            #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\`
            #### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
            
            <details><summary>Show Plan</summary>
            
            \`\`\`\n
            ${process.env.PLAN}
            \`\`\`
            
            </details>`;
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })
      
      - name: Terraform Apply
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: terraform apply -auto-approve

このワークフローでは:

  1. プルリクエスト時に terraform plan を実行し、変更内容をコメントとして表示
  2. メインブランチへのプッシュ時に terraform apply を自動実行
  3. コード品質チェック(フォーマット、検証)を各ステップで実施

より安全な運用のためには、以下のようなプラクティスも検討すべきです:

  • 環境分離: 開発、ステージング、本番環境ごとに異なるワークフローを設定
  • 承認プロセス: 重要な環境(本番など)への適用前に手動承認ステップを追加
  • 状態ファイルのリモート保存: S3やTerraform Cloudなどでステートを安全に管理

AWS CodePipelineとTerraformの組み合わせ

AWS内でインフラを管理している場合、AWS CodePipelineとTerraformを組み合わせることで、AWSネイティブのCI/CDパイプラインを構築できます。

典型的なAWS CodePipelineの構成は以下のようになります:

  1. Source Stage: AWS CodeCommitやGitHubからTerraformコードを取得
  2. Build Stage: AWS CodeBuildでTerraform初期化、検証、プラン生成
  3. Approval Stage: 必要に応じて手動承認ステップを追加
  4. Deploy Stage: CodeBuildでTerraform適用を実行

AWS CodeBuildのbuildspec.yml例:

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.9
    commands:
      - wget https://releases.hashicorp.com/terraform/1.3.0/terraform_1.3.0_linux_amd64.zip
      - unzip terraform_1.3.0_linux_amd64.zip
      - mv terraform /usr/local/bin/
  
  pre_build:
    commands:
      - echo "Initializing Terraform..."
      - terraform init
      - terraform validate
  
  build:
    commands:
      - echo "Planning Terraform changes..."
      - terraform plan -out=tfplan
      - terraform show -json tfplan > tfplan.json
  
  post_build:
    commands:
      - if [ "$CODEBUILD_WEBHOOK_EVENT" = "PULL_REQUEST_MERGED" ] || [ "$CODEBUILD_WEBHOOK_EVENT" = "" ]; then
          echo "Applying Terraform changes...";
          terraform apply -auto-approve tfplan;
        else
          echo "Skipping apply for non-merged PR events";
        fi

artifacts:
  files:
    - tfplan.json
    - terraform.tfstate

AWS CodePipelineをさらに強化するためのベストプラクティス:

  • 環境変数の管理: AWS Systems Manager Parameter StoreやAWS Secrets Managerを利用
  • クロスアカウントデプロイ: 異なるAWSアカウントへのデプロイを安全に管理
  • ドリフト検出: 定期的にインフラのドリフト(手動変更)を検出するジョブを追加

AWSのインフラ運用におけるCodePipelineとTerraformの組み合わせは、特に以下のような場合に効果的です:

  • AWS内のリソースが多い環境
  • セキュリティ要件が厳しく、AWSのIAM統合が必要な場合
  • 複数のAWSアカウントやリージョンにまたがる環境

この組み合わせにより、AWSネイティブのセキュリティ機能とモニタリング機能を活用しながら、Terraformによるインフラストラクチャのコード化のメリットを享受できます。

コメント

タイトルとURLをコピーしました