Skip to content

Instantly share code, notes, and snippets.

@iml1111
Created October 16, 2023 11:47
Show Gist options
  • Save iml1111/c2d629ba3c80024ece88d4bc19ceae42 to your computer and use it in GitHub Desktop.
Save iml1111/c2d629ba3c80024ece88d4bc19ceae42 to your computer and use it in GitHub Desktop.
[Terraform] ALB + Target group으로 확장성 있는 인프라 만들어보기
data "aws_vpc" "default" {
default = true
}
data "aws_subnets" "all" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
data "aws_security_group" "default" {
vpc_id = data.aws_vpc.default.id
name = "default"
}
data "aws_elb_service_account" "this" {}
data "aws_acm_certificate" "this" {
domain = var.acm_domain
}
data "aws_route53_zone" "this" {
name = var.domain
}
# S3 Log Bucket
resource "aws_s3_bucket" "logs" {
bucket = var.alb_log_bucket_name
force_destroy = true
}
resource "aws_s3_bucket_ownership_controls" "logs_ownership_controls" {
bucket = aws_s3_bucket.logs.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_acl" "log" {
depends_on = [aws_s3_bucket_ownership_controls.logs_ownership_controls]
bucket = aws_s3_bucket.logs.id
acl = "private"
}
resource "aws_s3_bucket_policy" "logs" {
bucket = aws_s3_bucket.logs.bucket
policy = data.aws_iam_policy_document.logs.json
}
# ELB ServiceACC에 대한 s3 bucket 작성 권한 할당
data "aws_iam_policy_document" "logs" {
statement {
actions = [
"s3:PutObject",
]
principals {
type = "AWS"
identifiers = [data.aws_elb_service_account.this.arn]
}
resources = [
"arn:aws:s3:::${var.alb_log_bucket_name}/*",
]
}
}
resource "aws_s3_bucket_lifecycle_configuration" "logs" {
bucket = aws_s3_bucket.logs.bucket
rule {
id = "logs_lifecycle"
# 오래된 로그파일 관리
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 60
storage_class = "GLACIER"
}
expiration {
days = 90
}
filter {
and {
prefix = "log/"
tags = {
rule = "log"
autoclean = "true"
}
}
}
status = "Enabled"
}
}
# 테스트를 위해 443, 80, 22번 포트를 전체 개방
resource "aws_security_group" "ssh_and_http" {
name = "allow_ssh_from_all"
description = "Allow SSH port from all"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_ssh_from_all"
}
}
# ALB
resource "aws_lb" "this" {
name = var.alb_name
internal = false
load_balancer_type = "application"
security_groups = [
data.aws_security_group.default.id,
aws_security_group.ssh_and_http.id
]
subnets = [
data.aws_subnets.all.ids[0],
data.aws_subnets.all.ids[2]
]
# enable_deletion_protection = true
access_logs {
bucket = aws_s3_bucket.logs.bucket
prefix = "log"
enabled = true
}
tags = {
Author = var.author
Environment = "dev"
}
}
resource "aws_lb_target_group" "this" {
name = var.target_group_name
port = 80
protocol = "HTTP"
vpc_id = data.aws_vpc.default.id
health_check {
interval = 30
path = "/"
healthy_threshold = 3
unhealthy_threshold = 3
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.this.arn
port = "80"
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.this.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = data.aws_acm_certificate.this.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.this.arn
}
}
# EC2 & Attachment
resource "aws_key_pair" "web_admin" {
key_name = var.ec2_key_pair_name
public_key = file("./admin_key_pair.pub")
}
resource "aws_instance" "this" {
count = var.num_of_instances
ami = "ami-003bb1772f36a39a3" # 20.04 LTS
instance_type = "t2.micro"
key_name = aws_key_pair.web_admin.key_name
vpc_security_group_ids = [
data.aws_security_group.default.id,
aws_security_group.ssh_and_http.id,
]
user_data = file("./install_apache.sh")
tags = {
Name = "${var.instance_name} ${count.index}",
Author = var.author
}
}
resource "aws_lb_target_group_attachment" "this" {
count = length(aws_instance.this)
target_group_arn = aws_lb_target_group.this.arn
target_id = aws_instance.this[count.index].id
port = 80
}
# Route53 & Domain
resource "aws_route53_record" "record" {
zone_id = data.aws_route53_zone.this.zone_id
name = "${var.sub_domain}.${var.domain}"
type = "A"
alias {
name = aws_lb.this.dns_name
zone_id = aws_lb.this.zone_id
evaluate_target_health = false
}
}
output "alb_dns_name" {
value = aws_lb.this.dns_name
}
provider "aws" {
region = "ap-northeast-2"
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
variable "author" {
type = string
description = "author"
default = "IML"
}
variable "domain" {
type = string
description = "servcie domain"
default = "example.com"
}
variable "sub_domain" {
type = string
description = "sub domain"
default = "load-balancer"
}
variable "acm_domain" {
type = string
description = "ACM domain"
default = "*.example.com"
}
variable "instance_name" {
type = string
description = "EC2 name"
default = "IML Web Server Instance"
}
variable "ec2_key_pair_name" {
type = string
description = "EC2 Key pair name"
default = "iml_admin_key_pair"
}
variable "alb_name" {
type = string
default = "iml-alb"
}
variable "alb_log_bucket_name" {
type = string
default = "iml-alb-access-logs"
}
variable "target_group_name" {
type = string
default = "iml-target-group"
}
variable "num_of_instances" {
description = "Number of instances to create and attach to ALB"
type = string
default = 3
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment