Давайте рассмотрим архитектуру, которую мы собрали в Части 1.
Ознакомьтесь с частью 1
- основной веб-сайт, размещенный на www.
субдомене
- приложение html / js / css, размещенное в корзине S3
- облачный дистрибутив для предоставления нам https
URL
- сертификат, который будет использоваться с облачным распределением для этого домена
- серию небольших URL, которые будут перенаправлять на основной веб-сайт
Давайте начнем строить терраформу
создайте каталог вашего проекта
- вам нужен main.tf для хранения всех ваших ресурсов
- вам нужен файл variables.tf для хранения ваших входных данных в вашей инфраструктуре.
- вам нужен файл var для хранения значений ваших входных данных для вашей инфраструктуры
создайте свои исходные файлы tf
Основной веб-сайт, который мы хотим создать, - www.example.com.
resource "aws_s3_bucket" "logs" { bucket = "${var.site_name}-site-logs" acl = "log-delivery-write" }
resource "aws_s3_bucket" "www_site" { bucket = "www.${var.site_name}"
logging { target_bucket = "${aws_s3_bucket.logs.bucket}" target_prefix = "www.${var.site_name}/" }
website { index_document = "index.html" } }
variables.tf
variable "site_name" {
description = "My site"
}
вар-файлы / my-site.tf
site_name = "mysite.com"
Я считаю, что лучше всего мы учимся, когда видим, как все ломается! И здесь есть возможность что-то сломать.
Зачем помещать журналы доступа в отдельную корзину?
Давайте упростим задачу, поместив журналы доступа в ту же корзину, что и веб-сайт. Зачем мне 2 ведра?
resource "aws_s3_bucket" "www_site" { bucket = "www.${var.site_name}"
logging { target_bucket = "www.${var.site_name}" }
website { index_document = "index.html" } }
Спланируйте и примените свой терраформ, а затем посетите свой веб-сайт напрямую через URL-адрес веб-сайта S3. Обновите страницу несколько раз, а затем посмотрите содержимое корзины S3.
- Ваши журналы доступа теперь также общедоступны, потому что к ним можно получить доступ через URL-адрес вашего веб-сайта.
- В ваших журналах доступа длинные и непонятные имена файлов, и они засоряют ваш каталог. Если вы выполняете развертывание с использованием
aws s3 sync
в своем сегменте, вам придется удалять журналы доступа каждый раз при развертывании. - Подождите 10 минут и просмотрите активность в журналах доступа. Вы заметите, что в процессе создания файла, содержащего ваши журналы доступа, будет создан журнал доступа к процессу создания файла, содержащего ваши журналы доступа и т. Д., Т. Д. И т. Д.
Я делал это раньше. Я был так сбит с толку. Используйте отдельное ведро.
Создайте свой сертификат
Нам нужен сертификат, который мы можем получить бесплатно через ACM, но есть одна загвоздка.
resource "aws_acm_certificate" "cert" {
domain = "www.example.com"
}
Применение этого ресурса terraform начнет процесс запроса сертификата, но сертификат необходимо утвердить и создать вне канала. Есть два способа справиться с этим сценарием
- Не управляйте сертификатом с помощью terraform. Создайте его вручную и перетащите ARN сертификата везде, где вам нужно его использовать.
- Управляйте сертификатом с помощью terraform, но создайте его вручную, а затем используйте
terraform import
для импорта ресурса ПОСЛЕ его утверждения и создания.
Теперь мы можем создать дистрибутив Cloudfront и завершить соединение частей вместе:
resource "aws_cloudfront_origin_access_identity" "origin_access_identity" { comment = "cloudfront origin access identity" }
resource "aws_cloudfront_distribution" "website_cdn" { enabled = true price_class = "PriceClass_200" http_version = "http1.1" aliases = ["www.${var.site_name}"]
origin { origin_id = "origin-bucket-${aws_s3_bucket.www_site.id}" domain_name = "www.${var.site_name}.s3.us-east-2.amazonaws.com"
s3_origin_config { origin_access_identity = "${aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path}" } }
default_root_object = "index.html"
default_cache_behavior { allowed_methods = ["GET", "HEAD"] cached_methods = ["GET", "HEAD"] target_origin_id = "origin-bucket-${aws_s3_bucket.www_site.id}"
min_ttl = "0" default_ttl = "300" //3600 max_ttl = "1200" //86400
// This redirects any HTTP request to HTTPS. Security first! viewer_protocol_policy = "redirect-to-https" compress = true
forwarded_values { query_string = false
cookies { forward = "none" } } }
restrictions { geo_restriction { restriction_type = "none" } }
viewer_certificate { acm_certificate_arn = "${aws_acm_certificate.cert.arn}" ssl_support_method = "sni-only" }
}
Здесь несколько важных пунктов
aws_cloudfront_origin_access_identity
создаст это для вас в терраформе и будет управлять им. Вы можете либо создать и совместно использовать удостоверение доступа к источнику для нескольких распределений, либо использовать одно удостоверение доступа к источнику для каждого распределения.- Политика протокола просмотра
redirect-http-to-https
для обеспеченияhttps
соблюдения посетителей сайта
Заблокируйте ковш S3
Политика корзины позволяет нам определять безопасность корзины. В этом сценарии мы можем сохранить сегмент приватным и доступным только для Cloudfront с помощью Origin Access Identity. Мы можем выразить это в политике корзины:
main.tf
data "template_file" "bucket_policy" { template = "${file("bucket_policy.json")} vars { origin_access_identity_arn = "${aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path}" bucket = "${aws_s3_bucket.www_site.arn}" } }
resource "aws_s3_bucket" "www_site" { bucket = "www.${var.site_name}" policy = "${data.template_file.bucket_policy.rendered}" ... }
bucket_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OnlyCloudfrontReadAccess",
"Principal": {
"AWS": "${origin_access_identity_arn}"
},
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::${bucket}/*"
}
]
}
Создайте запись DNS
main.tf
resource "aws_route53_record" "www_site" {
zone_id = "${data.aws_route53_zone.site.zone_id}"
name = "www.${var.site_name}"
type = "A"
alias {
name = "${aws_cloudfront_distribution.website_cdn.domain_name}"
zone_id = "${aws_cloudfront_distribution.website_cdn.hosted_zone_id}"
evaluate_target_health = false
}
}
Примените свой терраформ и проверьте его.
Написание автоматических тестов для вашей инфраструктуры
Как и в любом проекте программирования, вы хотите убедиться, что у вас есть тесты для вашего кода. Но мы пишем terraform, а для terraform нет тестового раннера, или есть?
Все, что нам нужно для тестирования нашей терраформы, - это любой язык, который позволяет нам писать веб-запросы. Мы создадим 2 набора тестов, чтобы убедиться, что на mysite.com все работает.
Создайте тесты для проверки конфигурации вашего сегмента
s3_bucket_spec.rb
require 'serverspec'
context 's3 bucket' do
describe command('aws s3 ls s3://dperez-test-bucket') do its(:stdout) { should_match /Access Denied/ } end
describe command('curl -i https://s3.amazonaws.com/dperez-test-bucket') do its(:stdout) { should_match /Access Denied/ } end end
context 'cloudfront' do describe command('curl -i https://www.mysite.com') do its(:stdout) { should_match /200 OK/ } end
describe command('curl -i http://www.mysite.com') do its(:stdout) { should_match /301 Redirect/ } end end
Запустите тесты с помощью rspec, чтобы проверить только что созданную инфраструктуру.
Если вам понравилась статья, посетите мой сайт www.intricatecloud.io или подпишитесь на мой список рассылки здесь, чтобы узнать больше о различных типах приложений, созданных на AWS.