Terraformを実践的な使い方ーCloudFrontからS3へのアクセス制御をOACを使って正しく設定する編

Terraformを使ってS3+CloudFront構成の静的サイトを構築してみます。

  • やること
    • S3+CloudFrontで静的サイト構築
    • Origin access control settings(OAC)を使ってアクセス制御(AWS推奨のやつ)
  • どうやってやるか
    • Terraformを使います
      • Terraformの使い方は以下の点に注意し、実践的な方法で記載
        • Terraformバージョンを固定する
        • プロバイダーバージョンを指定する
        • tfstateファイルはS3で管理するようにする
        • インフラリソースは簡単に削除できないように、削除保護設定をしておく
        •  tfstateファイルを管理するS3バケットの作成
          • tfstateを管理するS3バケットは手動で作成する
        •  実行前に以下のコマンドを実行し、安全にインフラ構築する
          • terraform fmt
          • terraform validate
          • tflint
          • terraform plan

AWSマネージメントコンソール画面から、S3+CloudFrontでOAC使う方法は以下の記事をご参照ください。

http://54.95.217.231/it/aws-cloudfront-s3-oac.html

Terraformの基本的な使い方は以下の記事をご参照ください

http://54.95.217.231/it/terraform_best_practice.html

本記事では「TerraformでCloudFrontからS3へのアクセス制御をOrigin access control settings(OAC)を使って正しく設定する方法」を題材に、実践でTerraformを使う際のポイントを記載しています。色々な環境構築の基礎知識となり、応用可能な情報となります。

まずは、Terraformソースコードを作成していきます。

スポンサーリンク

Terraformソースコード

4つのファイルを使用します。

  • provider.tf
    • 以下のような情報を記載します。
      • terraformバージョン
      • AWSプロバイダーの定義
      • tfstateファイルを管理する場所の定義
  • variables.tf
    • ローカル変数の管理
  • aws_s3_bucket.tf
    • S3バケットを管理
  • aws_cloudfront_distribution.tf
    • CloudFrontを管理

次に、4つのファイルに記載する内容について記載していきます。

ファイル名:provider.tf


# terraformバージョンを固定
terraform {
  required_version = "1.3.9"
}

# AWSプロバイダーの定義
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}


#tfstateファイルを管理するS3バケットを定義
terraform {
  backend "s3" {
    bucket = "{tfstateファイルを管理するS3バケット名}"                #バケット名
    key    = "terraform-test/terraform.tfstate" #tfstateファイルごとに異なる任意の値
    region = "ap-northeast-1"
  }
}

ファイル名:variables.tf


locals {
  s3_bucket_name = {
    public = "{作成するバケット名}"
  }
}

ファイル名:aws_s3_bucket.tf


# S3バケット作成
resource "aws_s3_bucket" "terraform_develop" {
  bucket = local.s3_bucket_name.public
  # 削除保護
  lifecycle {
    prevent_destroy = true
  }
}
# バケットポリシー
resource "aws_s3_bucket_policy" "terraform_develop" {
  bucket = aws_s3_bucket.terraform_develop.id
  policy = data.aws_iam_policy_document.s3_develop_policy.json
}

# CloudFrontからのアクセスのみを許可
data "aws_iam_policy_document" "s3_develop_policy" {
  statement {
    principals {
      type        = "Service"
      identifiers = ["cloudfront.amazonaws.com"]
    }
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.terraform_develop.arn}/*"]
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = [aws_cloudfront_distribution.terraform_develop.arn]
    }
  }
}

ファイル名:aws_cloudfront_distribution.tf


# OAC作成
resource "aws_cloudfront_origin_access_control" "terraform_develop" {
  name                              = "terraform_develop"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}
# ディストリビューション作成
resource "aws_cloudfront_distribution" "terraform_develop" {
  enabled = true
  # オリジン設定
  origin {
    origin_id   = aws_s3_bucket.terraform_develop.id
    domain_name = aws_s3_bucket.terraform_develop.bucket_regional_domain_name
    // OACを設定
    origin_access_control_id = aws_cloudfront_origin_access_control.terraform_develop.id
  }
  # 削除保護
  lifecycle {
    prevent_destroy = true
  }
  # ビヘイビア設定
  default_cache_behavior {
    target_origin_id       = aws_s3_bucket.terraform_develop.id
    viewer_protocol_policy = "redirect-to-https"
    cached_methods         = ["GET", "HEAD"]
    allowed_methods        = ["GET", "HEAD"]
    forwarded_values {
      query_string = false
      headers      = []
      cookies {
        forward = "none"
      }
    }
  }
  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }
  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

Terraformを実行して環境構築していきます!

Terraformの実行

以下のコマンドを実行していきます。

// tfstateファイルを管理するS3バケット作成
aws s3 mb s3://{tfstateファイルを管理するS3バケット}

//ワークスペースを初期化する
terraform init

// コードフォーマット
terraform fmt

// バリデーション
terraform validate

// 不正なコードを検出
tflint

// 実行計画を確認
terraform plan

// リソース作成
terraform apply

動作確認

以下の2点確認できればOKです。

  • S3にindex.htmlファイルを作成して、「https://ディストリビューションドメイン名/index.html」でアクセスできる
  • S3のオブジェクト URLでアクセスできないこと

あと片付け

Terraformファイル(.tfファイル)での、S3とCloudFrontの設定について、「prevent_destroy」を以下の通り変更します

  • 変更前:prevent_destroy = true
  • 変更後:prevent_destroy = false

削除不可の状態(削除保護されている状態)から削除可能に変更後、削除を行うイメージです。

以下のコマンドで作成したリソースを削除します。

terraform apply

terraform destroy

まとめ

「CloudFrontからS3へのアクセス制御をOrigin access control settings(OAC)を使って正しく設定する」方法を、Terraformの実践的な使い方で記載しました。

色々な環境構築に応用できるかと思います。Terraformの実践的な使い方のポイントを再度あげておきます

  • Terraformバージョンを固定する
  • プロバイダーバージョンを指定する
  • tfstateファイルはS3で管理するようにする
  • インフラリソースは簡単に削除できないように、削除保護設定をしておく
  •  tfstateファイルを管理するS3バケットの作成
    • tfstateを管理するS3バケットは手動で作成する
  • 実行前に以下のコマンドを実行し、安全にインフラ構築する
    • terraform fmt
    • terraform validate
    • tflint
    • terraform plan

 

最後にCloudFrontのOACに関する公式記事を載せておきます。

Amazon CloudFront オリジンアクセスコントロール(OAC)のご紹介 | Amazon Web Services
本記事は、「Amazon CloudFront introduces Origin Access Contro