0
0

More than 1 year has passed since last update.

Terraform未経験からS3, CloudFrontの作成ができるようになるまでにやったこと

Posted at

本記事について

terraformを初心者がこなすためにつまづく点やどうするべきかといったポイントのメモ

対象

  • UdemyでAWSについて学んだことのあるレベルを想定
  • terraformは使ったことないけど、なんとなく概要はわかる。

本記事でやること

環境構築
STEP1 S3作る
STEP2 S3とCloudFront作る

環境

Mac OS 12.5 M2

terraformとは?

AWSに関しては、

AWSの設定書いて、terraform apply したら反映されるやつ。

インストール

dockerで構築するって手もあるが、tfenvのほうが楽そうだったのでtfenvを選択。

$ brew install tfenv

# バージョン確認
$ tfenv list-remote

# インストールでバージョン指定しなかったら失敗した。指定したら成功した。
$ tfenv install 1.2.8
$ terraform -v

AWSCLIもインストール

IAMでユーザー作ってaccess_keyを発行し、登録しておく。
以下のようにファイル作られていればOK

~$ cat .aws/config
[default]
region = ap-northeast-1
output = json
~$ cat .aws/credentials
[default]
aws_access_key_id = hogehoge
aws_secret_access_key = hogehoge

作業フォルダ作成

いろいろベストプラクティスなフォルダ構成の記事は探したが、
初学者に求められるフォルダ構成はシンプルさだけかなと思うので、めっちゃシンプルな構成にする。
共通化は考えない。

first-terraform(master)$ tree .           
.
├── README.md
├── dev
│   ├── main.tf
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
└── docs
    ├── 00_command.md
    ├── 10_s3.md
    └── 11_cloudfront.md

README.md このリポジトリでなにをする?とかをメモ
dev 作業フォルダ。prodを作る気はないが直下に作るのが嫌だったので。
dev/main.tf ここにterraformの中身書いていく。ファイル分割は必要に思えるまでしない
docs 残しておくべきメモの量が多く、issueやPRだと管理しづらかったためドキュメントフォルダを作った。

git管理は作業ディレクトリ直下。

.gitignore
#  Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# .tfvars files
*.tfvars

このgitignoreはどこかで拾った。

初期化

# devフォルダ内で実行する
# lockファイルとかができる。
terraform init

STEP1 S3作る

こうなった。

main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.29.0"
    }
  }

  required_version = "1.2.8"
}

provider "aws" {
  profile = "default"
}

resource "aws_s3_bucket" "b" {
  bucket = "teach-tf-test-bucket"

  tags = {
    Name        = "teach-tf-test-bucket"
    Environment = "Dev"
  }
}

resource "aws_s3_bucket_ownership_controls" "b" {
  bucket = aws_s3_bucket.b.id

  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}

resource "aws_s3_bucket_public_access_block" "b" {
  bucket = aws_s3_bucket.b.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
$ terraform fmt
$ terraform validate
Success! The configuration is valid.

# 確認
$ terraform plan
# 反映
$ terraform apply

公式のaws-get-startedを参考に書き換えている。

required_providersのawsのversionはterraform registryを見て最新を取得
https://registry.terraform.io/providers/hashicorp/aws/latest

required_versionはterraform -vで出たやつ

providerの設定はローカルであればprofileに書いてあるやつそのまま使えばいいかなということで、profileから情報取得するようにした。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs#shared-configuration-and-credentials-files

regionはprofileに記載されているので省略。

resourceの書き方
https://www.terraform.io/language/resources/syntax#resource-syntax

s3の設定は主にドキュメントを見ている。

ただしここに載っているサンプルの設定はコンソールで手動で設定するときの「推奨」の設定にはなっていない。
そこで推奨の設定になるようにサンプルとは一部を変更して設定した。

具体的には

  • aws_s3_bucket_ownership_controls
  • aws_s3_bucket_public_access_block

の2つ

terraform.tfstateについて

いろんな記事でterraform.tfstateはS3に配置することが推奨されている。
しかし、本記事においては環境は、「作ったら削除する」使い捨て環境なのでtfstateを管理する必要がない。そこでS3にアップロードしないようにしている。

STEP2 S3とCloudFront作る

main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.29.0"
    }
  }

  required_version = "1.2.8"
}

provider "aws" {
  profile = "default"
}

resource "aws_s3_bucket" "b" {
  bucket = "teach-tf-test-bucket"

  tags = {
    Name        = "teach-tf-test-bucket"
    Environment = "Dev"
  }
}

resource "aws_s3_bucket_ownership_controls" "b" {
  bucket = aws_s3_bucket.b.id

  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}

resource "aws_s3_bucket_public_access_block" "b" {
  bucket = aws_s3_bucket.b.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_policy" "b" {
  bucket = aws_s3_bucket.b.id
  policy = data.aws_iam_policy_document.s3_cf_policy.json
}

data "aws_iam_policy_document" "s3_cf_policy" {
  statement {
    sid    = "AllowCloudFrontServicePrincipalReadOnly"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudfront.amazonaws.com"]
    }

    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.b.arn}/*"]

    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = [aws_cloudfront_distribution.s3_distribution.arn]
    }
  }
}

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = aws_s3_bucket.b.bucket_regional_domain_name
    origin_id   = aws_s3_bucket.b.id

    origin_access_control_id = aws_cloudfront_origin_access_control.s3_oac.id
  }

  default_cache_behavior {
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = aws_s3_bucket.b.id
    cache_policy_id        = data.aws_cloudfront_cache_policy.default.id
    compress               = true
  }

  restrictions {
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["JP"]
    }
  }

  enabled         = true
  is_ipv6_enabled = true

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

data "aws_cloudfront_cache_policy" "default" {
  name = "Managed-CachingOptimized"
}

resource "aws_cloudfront_origin_access_control" "s3_oac" {
  name                              = "teach-tf-test-oac"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

ドキュメント

こちらもS3と同様にterraformのサンプルを参考にしつつ、手動でコンソールでCloudFrontを一度作成してみて、それと同一になるようにterraform側で設定した。

ポイントは以下

■ default_cache_behaviorのcache_policy_id
サンプルと同様の方法でやるとLegacyになるのでcache_policy_idを使う
設定の仕方

■ aws_cloudfront_origin_access_control

OAIはLegacyなのでOACを使う。
参考

リファレンス

descriptionはRequiredって書いてあるけどなくても大丈夫そうな。

aws_s3_bucket_policyは[Developer Guide]とterraformのドキュメント見て同じになるように設定

これをapplyしてS3にオブジェクトアップロードするとcloudfront経由で取得できる。

リンク例
https://d1hogehogevm.cloudfront.net/box_3d.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0