Criar bucket S3 com CDN na AWS utilizando OpenTofu
Como Criar um Bucket S3 com CDN na AWS usando OpenTofu
No meu último artigo eu mostrei como criar uma função Lambda com uma API usando Nodejs, Api Gateway e OpenTofu e percebi que os áudios que utilizei no artigo, precisavam ser armazenados em algum local, então eu criei um bucket e conectei ao Cloudfront da AWS para servir os áutios. E nesse artigo eu irei mostrar como você pode fazer o mesmo.
Pré-requisitos
Certifique-se de ter as seguintes ferramentas instaladas em seu sistema:
Opcional: Caso você queira utilizar um domínio personalizado, você precisa ter um domínio registrado e configurado no Route53.
Passo 1: Criar o projeto e os arquivos necessários
Crie um diretório chamado tofu no seu projeto:
Windows PowerShell | Unix/Mac |
---|---|
|
|
Passo 2: Configurar o arquivo variables.tf
Obs: Você pode utilizar o nome de variáveis que achar melhor, só basta lembrar de alterar no arquivo main.tf
também.
variable "region" {
description = "The AWS region to deploy resources in"
type = string
default = "us-east-1" # Altere para a região que deseja
}
variable "profile" {
description = "Default AWS profile to use for deployment"
type = string
default = "meu_profile" # Altere para o seu profile
}
variable "blog_bucket_name" {
description = "The name of the S3 bucket to create"
type = string
default = "meu_bucket" # Altere para o nome do seu bucket
}
variable "use_custom_domain" {
description = "Determines whether to use a custom domain for the CloudFront distribution"
type = bool
default = true # Altere para false se não deseja utilizar um domínio personalizado
}
variable "route_53_zone_id" {
description = "The Route 53 zone ID to use for the CloudFront distribution"
type = string
default = "zone_id" # Altere para o ID da sua zona no Route53
}
variable "audio_blog_alias" {
description = "The alias to use for the CloudFront distribution"
type = string
default = "meu_sub_dominio" # Altere para o subdomínio que deseja
}
variable "certificate_acm_id" {
description = "The ARN of the ACM certificate to use for the CloudFront distribution"
type = string
default = "acm_certificate_id" # Altere para o ID do certificado ACM
}
Passo 3: Configurar o arquivo main.tf
Crie um arquivo main.tf com o seguinte conteúdo:
provider "aws" {
region = var.region
profile = var.profile
}
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket" "blog_bucket" {
bucket = var.blog_bucket_name
force_destroy = true
tags = {
Name = var.blog_bucket_name
}
}
resource "aws_s3_bucket_public_access_block" "public_access_block" {
bucket = aws_s3_bucket.blog_bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_cloudfront_origin_access_identity" "origin_access_identity" {
comment = "OAI para o S3"
}
resource "aws_s3_bucket_policy" "blog_bucket_policy" {
bucket = aws_s3_bucket.blog_bucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn
}
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.blog_bucket.arn}/*"
},
]
})
}
resource "aws_cloudfront_distribution" "blog_audios_distribution" {
origin {
domain_name = aws_s3_bucket.blog_bucket.bucket_regional_domain_name
origin_id = aws_s3_bucket.blog_bucket.bucket
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path
}
}
enabled = true
is_ipv6_enabled = true
comment = "Distribuição CloudFront para os audios do blog"
aliases = var.use_custom_domain ? [var.audio_blog_alias] : []
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = aws_s3_bucket.blog_bucket.bucket
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 = var.use_custom_domain ? "arn:aws:acm:${var.region}:${data.aws_caller_identity.current.account_id}:certificate/${var.certificate_acm_id}" : null
ssl_support_method = var.use_custom_domain ? "sni-only" : null
minimum_protocol_version = "TLSv1.2_2021"
cloudfront_default_certificate = var.use_custom_domain ? null : true
}
}
resource "aws_route53_record" "my_cloudfront_alias" {
count = var.use_custom_domain ? 1 : 0
depends_on = [aws_cloudfront_distribution.blog_audios_distribution]
zone_id = var.route_53_zone_id
name = var.audio_blog_alias
type = "A"
alias {
name = aws_cloudfront_distribution.blog_audios_distribution.domain_name
zone_id = aws_cloudfront_distribution.blog_audios_distribution.hosted_zone_id
evaluate_target_health = false
}
}
output "cloudfront_domain_name" {
value = aws_cloudfront_distribution.blog_audios_distribution.domain_name
}
Passo 3: Deploy
Dentro da pasta tofu
, execute os seguintes comandos para fazer o deploy:
tofu init
tofu plan
tofu apply
Após o deploy, você verá a URL da Distribuição do Cloudformation que está servindo os arquivos do seu bucket.
Algo parecido com cloudfront_id.cloudfront.net
Passo 4: Testando a distribuição
Para testar vamos subir um arquivo para o bucket e acessar a URL da distribuição.
aws s3 cp <caminho_do_arquivo> s3://<nome_do_bucket> --profile meu_profile
Após subir o arquivo, acesse a URL da distribuição no navegador.
Vamos supor que você realizou o upload de uma foto para o S3, ao acessar a url da distribuição, você verá a foto que subiu.
Passo 5: Destruindo a Infraestrutura após os testes
Para destruir a infraestrutura, execute o seguinte comando:
tofu destroy
Conclusão
Com isso agora posso servir meus arquivos de áudio de forma segura e rápida.