[Terraform]CloudFront+S3でホームページを作る
CloudFrontちゃんと使ったことなかったので勉強用に、ChatGPTにTerraformを生成して、CloudFront+S3でホームページを作ってみました。
目次
GPT Log
https://chat.openai.com/share/aa5e99ab-91c0-49a4-bc43-fc7422ea7fde
ChatGPT Plus使用
ディレクトリ構成
* index.html
* main.tf
ソース
index.html
<html>
<body>
<h1>Hello, World</h1>
<h2>This is shikoan's page</h2>
</body>
</html>
main.tf
terraform {
backend "local" {
path = ".cache/terraform.tfstate"
}
}
provider "aws" {
region = "ap-northeast-1"
profile = "develop"
}
resource "aws_s3_bucket_policy" "my_bucket_policy" {
bucket = aws_s3_bucket.my_bucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.my_bucket.arn}/*"
}
]
})
}
# S3 ACL
resource "aws_s3_bucket" "my_bucket" {
bucket = "shikoan-homepage-bucket" # Enter your backet name
}
resource "aws_s3_bucket_ownership_controls" "bucket_ownership_control" {
bucket = aws_s3_bucket.my_bucket.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_public_access_block" "bucket_public_access_block" {
bucket = aws_s3_bucket.my_bucket.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_acl" "my_bucket_acl" {
depends_on = [
aws_s3_bucket_ownership_controls.bucket_ownership_control,
aws_s3_bucket_public_access_block.bucket_public_access_block,
]
bucket = aws_s3_bucket.my_bucket.id
acl = "public-read"
}
resource "aws_s3_object" "index_html" {
bucket = aws_s3_bucket.my_bucket.bucket
key = "index.html"
source = "index.html" # "path/to/your/local/index.html"
# acl = "public-read"
content_type = "text/html"
}
resource "aws_s3_bucket_website_configuration" "my_bucket_website" {
bucket = aws_s3_bucket.my_bucket.id
index_document {
suffix = "index.html"
}
}
# CloudFront
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = aws_s3_bucket.my_bucket.bucket_regional_domain_name
origin_id = "S3-myBucket"
s3_origin_config {
origin_access_identity = "origin-access-identity/cloudfront/${aws_cloudfront_origin_access_identity.s3_oai.id}"
}
}
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "S3-myBucket"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_100"
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
resource "aws_cloudfront_origin_access_identity" "s3_oai" {
comment = "OAI for ${aws_s3_bucket.my_bucket.bucket}"
}
output "s3_bucket_url" {
value = "http://${aws_s3_bucket_website_configuration.my_bucket_website.website_endpoint}"
description = "URL for the S3 bucket hosting the website"
}
output "cloudfront_distribution_url" {
value = "https://${aws_cloudfront_distribution.s3_distribution.domain_name}"
description = "URL for the CloudFront distribution"
}
結果
CloudFrontもS3も見ることができた(S3のバケットを全公開にしたのでそれはそう)。
ちなみにCloudFrontの画面はこんな感じ。初めて見たけど、オリジンがきちんとS3を向いている。
Terraformのコード1行で、CloudFrontでHTTP→HTTPSのリダイレクトが効いているのがいけてる。ACMなどは一切インストールしていない。
ハマりどころ
ChatGPTがdecryptedなTerraformのコードを書いてくる
例えば、最初の出してきたは、websiteもaclもDecrypted。このへんはTerraformの公式文書を見ながら書き直した
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
acl = "public-read"
website {
index_document = "index.html"
}
}
バケットオブジェクトにACLを設定するとアップロードできない
resource "aws_s3_object" "index_html" {
bucket = aws_s3_bucket.my_bucket.bucket
key = "index.html"
source = "index.html" # "path/to/your/local/index.html"
# acl = "public-read"
content_type = "text/html"
}
このようにかけばローカルのindex.htmlを、S3にアップロードできるが、aclを設定するとアップロードに失敗する。
出てきたホームページが403
S3のダイレクトのリンクも、CloudFrontのリンクも403を出す。
これはS3のバケットポリシーを書いていなかったためで、追加したら表示できるようになった。
感想
ChatGPT+Terraformはそんなにハマることはないけど、これは割とハマったほうかな
1回でterraform apply
が通らないこともあるので、2回やるとうまくいくと思う。
勉強用なので、完了したらterraform destroy
。ちゃんと使うならS3バックエンドがいいと思う。
Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内
技術書コーナー
北海道の駅巡りコーナー