概要
タイトルが長い。
個人プロジェクトでSSL対応したWebサイトを作る機会があって、折角なので無料のACM(Aws Certificate Manager)を使ってみました。
そこそこ安く、SSL対応したWebサイトを構築します。
インフラはほぼAWSを使っています。
なぜこれらの技術を採用したか
S3
WebサイトはWordPress等で構築でも良かったのですが、サーバ費用をかけたくなかったため。
middlemanでビルドした静的WebをS3にホストしています。
CloudFront
S3 + ACMの組み合わせだと必須だったため、仕方なく使っています。
わざわざCloudFrontを使うほどのトラフィックではない。
S3で直接ACM使えたらいいのになぁ。
Aws Certificate Manager
Let’s Encryptでも良かったけど、サーバの運用とかしたくなかったため。
というか、そもそもACMを使ってみたいというモチベーションだった。
Route53
何かと相性が良いので。
ドメインはAWS外のサービスで取りました。
Middleman
静的サイトジェネレーターです。
https://middlemanapp.com/jp/
要件的には静的WebでOKかつ自分しか記事更新しないので、middleman-blogを採用しました。
もし非エンジニアの人が記事書くようなプロジェクトだと、middlemanは採用しづらいですね...
terraform
INFRASTRUCTURE AS CODEです。
https://www.terraform.io/
AWSの管理画面でぽちぽちするのがあまり好きでは無いので、なるだけterraformでAWSリソースの構築をしました。
記事時点では v0.6.15 を使っています。
構成
クライアント → CloudFront → S3 ← middleman ← おれ
terraformのtf
こちらを大変参考にさせて頂きました。
クラメソさんの記事いつもお世話になっております
そしてこの記事の一番価値あるのはここだよ
variable "name" { default = "bucket-name.here" }
resource "aws_cloudfront_origin_access_identity" "sample" {
comment = "${var.name}"
}
resource "template_file" "sample_s3_policy" {
template = "${file(concat(path.module, "/sample_s3_policy.json.tpl"))}"
vars {
bucket_name = "${var.name}"
origin_access_identity = "${aws_cloudfront_origin_access_identity.sample.id}"
}
}
resource "aws_s3_bucket" "sample" {
bucket = "${var.name}"
acl = "private"
policy = "${template_file.sample_s3_policy.rendered}"
website {
index_document = "index.html"
error_document = "404.html"
}
}
resource "aws_cloudfront_distribution" "sample" {
enabled = true
comment = "${var.name}"
default_root_object = "index.html"
price_class = "PriceClass_200"
retain_on_delete = true
aliases = ["${var.name}", "www.${var.name}"]
origin {
domain_name = "${aws_s3_bucket.sample.website_endpoint}"
origin_id = "${var.name}"
custom_origin_config {
http_port = "80"
https_port = "443"
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "${aws_s3_bucket.sample.id}"
compress = true
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
acm_certificate_arn = "arn:aws:acm:us-east-1:xxxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1"
}
}
resource "aws_route53_zone" "sample" {
name = "${var.name}"
}
resource "aws_route53_record" "sample" {
zone_id = "${aws_route53_zone.sample.zone_id}"
name = "${var.name}"
type = "A"
alias {
name = "${aws_cloudfront_distribution.sample.domain_name}"
zone_id = "Z2FDTNDATAQYW2"
evaluate_target_health = false
}
}
resource "aws_route53_record" "www-sample" {
zone_id = "${aws_route53_zone.sample.zone_id}"
name = "www.${var.name}"
type = "A"
alias {
name = "${aws_cloudfront_distribution.sample.domain_name}"
zone_id = "Z2FDTNDATAQYW2"
evaluate_target_health = false
}
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${origin_access_identity}"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::${bucket_name}/*"
}
]
}
クラメソさんの記事をベースに作っていますが、いくつか変更点があります。
- CloudFrontのindexDocumentの設定
-
bucket-name.here/foo/index.html
に対して、bucket-name.here/foo
だけでアクセスできるようにしたかった - そのため
custom_origin_config
を設定している
-
- ACMを利用するためにCloudFrontの
viewer_certificate
の設定をしている
terraform管理外のリソース
できるだけterraformで完結したかったのですが、ACMに関してはまだterraformから扱えないようでしたので、管理画面からぽちぽちつくりました。
今回はwwwあり/なしそれぞれのドメインをあてているので、certificateもこの2つを含むものを作成しました。
また、ACM設定の際にメールの受信設定等が必要です。
メール受信するためにSESも使うのですが、同じくterraformから管理できないので管理画面からぽちぽちしました。
こちらを参考にさせて頂きました。
無事にACMの設定が完了するとarnがわかるので、その値をterraformのacm_certificate_arn
にセットします。
費用
月に100円〜200円程度でしょうか。
月額(ざっくり) | |
---|---|
ドメイン | 10 〜 100円 |
Route53 | 60円 |
S3 | 10円 |
CloudFront | 20円 |
まとめ
middlemanの話は無くても良かったですね...
(werckerの話も最初書いたけど関係ないから消した)
S3 + CloudFront + ACM を terraform で実現したい場合の参考になれば幸いです。