팀 프로젝트- 13회차

박형준·2024년 6월 26일

terraform 파일 구조
terraform 파일 구조
C:\Users\USER\Desktop\terraform-developments\VPC-infra
└─terraform
├─development
└─modules
├─VPC
...


대상 그룹 생성 ( 6회차 참고 )

로드 밸런서에 연결할 대상 그룹 생성

  • 작업 순서:

    • modules/target_group 폴더를 생성하고 main.tf 및 variables.tf 파일을 추가합니다.

    • development 폴더와 modules/target_group 폴더에서 main.tf 및 variables.tf 파일을 업데이트하여 region 및 VPC ID를 설정합니다.

  • 추가 설명

    • outputs.tf 파일에서는 vpc_id를 출력합니다. 이는 다른 모듈들이 VPC와 서브넷의 ID를 참조할 수 있도록 하기 위함입니다.

    • development 폴더의 main.tf 파일에서는 vpc 모듈과 target_group 모듈을 정의하고, vpc 모듈에서 출력된 vpc_id를 target_group 모듈에 전달합니다.

    • development 폴더의 variables.tf 파일에서는 region 변수를 정의하여 모든 모듈에서 사용할 수 있도록 합니다.


modules/VPC/outputs.tf

output "vpc_id" {
  description = "The ID of the VPC"
  value       = aws_vpc.terraform-vpc.id
}

output "public_subnets" {
  description = "The IDs of the public subnets"
  value       = [
    aws_subnet.terraform-BASTION-PUB-2A.id,
    aws_subnet.terraform-NGINX-PUB-2A.id,
    aws_subnet.terraform-NGINX-PUB-2C.id
  ]
}

output "private_subnets" {
  description = "The IDs of the private subnets"
  value       = [
    aws_subnet.terraform-TOMCAT-PRI-2A.id,
    aws_subnet.terraform-DB-PRI-2A.id,
    aws_subnet.terraform-TOMCAT-PRI-2C.id,
    aws_subnet.terraform-DB-PRI-2C.id
  ]
}

output "nat_gateway_id" {
  description = "The ID of the NAT Gateway"
  value       = aws_nat_gateway.terraform-nat-gw.id
}

output "nginx_security_group" {
  description = "The ID of the NGINX security group"
  value       = aws_security_group.terraform-sg-nginx.id
}

output "tomcat_security_group" {
  description = "The ID of the TOMCAT security group"
  value       = aws_security_group.terraform-sg-tomcat.id
}

output "db_security_group" {
  description = "The ID of the DB security group"
  value       = aws_security_group.terraform-sg-db.id
}

modules/target_group/main.tf

provider "aws" {
  region = var.region
}

resource "aws_lb_target_group" "nginx_target_group" {
  name     = "VEC-PRD-NGINX-GROUP"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    interval            = 30
    path                = "/"
    timeout             = 5
    healthy_threshold   = 5
    unhealthy_threshold = 2
    matcher             = "200"
  }

  target_type = "instance"
}

resource "aws_lb_target_group" "tomcat_target_group" {
  name     = "VEC-PRD-TOMCAT-GROUP"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    interval            = 30
    path                = "/"
    timeout             = 5
    healthy_threshold   = 5
    unhealthy_threshold = 2
    matcher             = "200"
  }

  target_type = "instance"
}

output "nginx_target_group_arn" {
  value = aws_lb_target_group.nginx_target_group.arn
}

output "tomcat_target_group_arn" {
  value = aws_lb_target_group.tomcat_target_group.arn
}

modules/target_group/variables.tf

variable "region" {
  description = "The AWS region to create resources in."
  type        = string
}

variable "vpc_id" {
  description = "The ID of the VPC to create resources in."
  type        = string
}

로드 밸런서 테라폼 격리화 ( 6회차 참고 )

사전 작업 ( 6회차 참고 )

  • route 53을 통해 도메인 지정, AWS Certificate Manager에서 인증서 요청

ALB 생성 ( 로드 밸런서 프로 비저닝 시간이 약간 소요 )

  • modules/load_balancer 파일 생성

modules/load_balancer/main.tf

provider "aws" {
  region = var.region
}

resource "aws_lb" "nginx_alb" {
  name               = "VEC-PRD-NGINX-ALB"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [var.nginx_security_group]
  subnets            = [var.nginx_subnet_2a, var.nginx_subnet_2c]

  enable_deletion_protection = false

  tags = {
    Name = "VEC-PRD-NGINX-ALB"
  }
}

resource "aws_lb_listener" "nginx_http_listener" {
  load_balancer_arn = aws_lb.nginx_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = var.nginx_target_group_arn
  }
}

resource "aws_lb_listener" "nginx_https_listener" {
  load_balancer_arn = aws_lb.nginx_alb.arn
  port              = "443"
  protocol          = "HTTPS"

  ssl_policy      = "ELBSecurityPolicy-2016-08"
  certificate_arn = var.acm_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = var.nginx_target_group_arn
  }
}

resource "aws_lb" "tomcat_alb" {
  name               = "VEC-PRD-TOMCAT-ALB"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [var.tomcat_security_group]
  subnets            = [var.tomcat_subnet_2a, var.tomcat_subnet_2c]

  enable_deletion_protection = false

  tags = {
    Name = "VEC-PRD-TOMCAT-ALB"
  }
}

resource "aws_lb_listener" "tomcat_http_listener" {
  load_balancer_arn = aws_lb.tomcat_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = var.tomcat_target_group_arn
  }
}

resource "aws_lb_listener" "tomcat_https_listener" {
  load_balancer_arn = aws_lb.tomcat_alb.arn
  port              = "443"
  protocol          = "HTTPS"

  ssl_policy      = "ELBSecurityPolicy-2016-08"
  certificate_arn = var.acm_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = var.tomcat_target_group_arn
  }
}

modules/load_balancer/variables.tf

variable "region" {
  description = "The AWS region to create resources in."
  type        = string
}

variable "nginx_subnet_2a" {
  description = "The ID of the NGINX public subnet in ap-northeast-2a."
  type        = string
}

variable "nginx_subnet_2c" {
  description = "The ID of the NGINX public subnet in ap-northeast-2c."
  type        = string
}

variable "nginx_security_group" {
  description = "The security group ID for the NGINX ALB."
  type        = string
}

variable "nginx_target_group_arn" {
  description = "The ARN of the target group for NGINX."
  type        = string
}

variable "tomcat_subnet_2a" {
  description = "The ID of the TOMCAT private subnet in ap-northeast-2a."
  type        = string
}

variable "tomcat_subnet_2c" {
  description = "The ID of the TOMCAT private subnet in ap-northeast-2c."
  type        = string
}

variable "tomcat_security_group" {
  description = "The security group ID for the TOMCAT ALB."
  type        = string
}

variable "tomcat_target_group_arn" {
  description = "The ARN of the target group for TOMCAT."
  type        = string
}

variable "acm_certificate_arn" {
  description = "The ARN of the ACM certificate for HTTPS listener."
  type        = string
}

modules/load_balancer/outputs.tf

output "nginx_alb_dns_name" {
  description = "The DNS name of the NGINX ALB"
  value       = aws_lb.nginx_alb.dns_name
}

output "nginx_alb_zone_id" {
  description = "The zone ID of the NGINX ALB"
  value       = aws_lb.nginx_alb.zone_id
}

설명

  • modules/load_balancer/main.tf: 두 개의 ALB를 생성하고, 각각의 HTTP 및 HTTPS 리스너를 설정합니다. HTTPS 리스너는 ACM 인증서를 사용합니다.

  • modules/load_balancer/variables.tf: 필요한 변수들을 정의합니다.

  • development/main.tf: load_balancer 모듈을 호출하여 ALB를 설정합니다. nginx와 tomcat에 대한 서브넷, 보안 그룹, 대상 그룹 및 ACM 인증서 ARN을 전달합니다.
    development/variables.tf: 지역 변수를 정의합니다.


route53에 호스팅할 레코드 생성 ( 6회차 참고 )

route53을 이용하여 레코드 생성

  • modules/route53 폴더 생성

modules/route53/main.tf


provider "aws" {
  region = var.region
}

resource "aws_route53_record" "www_record" {
  zone_id = var.zone_id
  name    = "www.soldesk-insightforge.site"
  type    = "A"

  alias {
    name                   = var.alb_dns_name
    zone_id                = var.alb_zone_id
    evaluate_target_health = true
  }
}

modules/route53/variables.tf

variable "region" {
  description = "The AWS region to create resources in."
  type        = string
}

variable "zone_id" {
  description = "The ID of the Route 53 hosted zone."
  type        = string
}

variable "alb_dns_name" {
  description = "The DNS name of the ALB."
  type        = string
}

variable "alb_zone_id" {
  description = "The zone ID of the ALB."
  type        = string
}

설명

  • 이제 modules/load_balancer에서 생성된 로드 밸런서를 modules/route53 모듈에서 참조하여 Route 53 레코드를 생성할 수 있습니다.

  • 이 구성을 통해 www.soldesk-insightforge.site 레코드를 생성하고, VEC-PRD-NGINX-ALB에 연결할 수 있습니다.

  • 레코드를 생성할 때 미리 생성해둔 호스팅 영역의 ID를 입력하여 생성


오토 스케일링 생성 ( 9회차 참고 )

오토 스케일링을 생성하기 위한 시작 템플릿 생성

  • VPC로 구성한 각 서브넷을 통해 시작 템플릿 작성

    • 시작 템플릿 이름: VEC-PRD-VPC-NGINX-PUB-2A
      이미지: Amazon Linux 2 (또는 원하는 Linux 배포판)
      인스턴스 유형: t2.micro
      키페어: soldesk.pem.pem
      서브넷: VEC-PRD-VPC-NGINX-PUB-2A
      보안 그룹: 기존 보안 그룹 선택 (VEC-PRD-VPC-NGINX-PUB-SG-2A)
      고급 네트워크 구성: 퍼블릭 IP 활성화

    • 시작 템플릿 이름: VEC-PRD-VPC-NGINX-PUB-2C
      이미지: Amazon Linux 2 (또는 원하는 Linux 배포판)
      인스턴스 유형: t2.micro
      키페어: soldesk.pem.pem
      서브넷: VEC-PRD-VPC-NGINX-PUB-2C
      보안 그룹: 기존 보안 그룹 선택 (VEC-PRD-VPC-NGINX-PUB-SG-2A)
      고급 네트워크 구성: 퍼블릭 IP 활성화

    • 시작 템플릿 이름: VEC-PRD-VPC-TOMCAT-PRI-2A
      이미지: Amazon Linux 2 (또는 원하는 Linux 배포판)
      인스턴스 유형: t2.micro
      키페어: soldesk.pem.pem
      서브넷: VEC-PRD-VPC-TOMCAT-PRI-2A
      보안 그룹: 기존 보안 그룹 선택 (VEC-PRD-VPC-TOMCAT-PRI-SG-2A)
      고급 네트워크 구성: 퍼블릭 IP 비활성화

    • 시작 템플릿 이름: VEC-PRD-VPC-TOMCAT-PRI-2C
      이미지: Amazon Linux 2 (또는 원하는 Linux 배포판)
      인스턴스 유형: t2.micro
      키페어: soldesk.pem.pem
      서브넷: VEC-PRD-VPC-TOMCAT-PRI-2C
      보안 그룹: 기존 보안 그룹 선택 (VEC-PRD-VPC-TOMCAT-PRI-SG-2A)
      고급 네트워크 구성: 퍼블릭 IP 비활성화

    • 시작 템플릿 이름: VEC-PRD-VPC-DB-PRI-2A
      이미지: Amazon Linux 2 (또는 원하는 Linux 배포판)
      인스턴스 유형: t2.micro
      키페어: soldesk.pem.pem
      서브넷: VEC-PRD-VPC-DB-PRI-2A
      보안 그룹: 기존 보안 그룹 선택 (VEC-PRD-VPC-DB-PRI-SG-2A)
      고급 네트워크 구성: 퍼블릭 IP 활성화

    • 시작 템플릿 이름: VEC-PRD-VPC-DB-PRI-2C
      이미지: Amazon Linux 2 (또는 원하는 Linux 배포판)
      인스턴스 유형: t2.micro
      키페어: soldesk.pem.pem
      서브넷: VEC-PRD-VPC-DB-PRI-2C
      보안 그룹: 기존 보안 그룹 선택 (VEC-PRD-VPC-DB-PRI-SG-2A)
      고급 네트워크 구성: 퍼블릭 IP 활성화


modules/launch_template/main.tf

provider "aws" {
  region = var.region
}

resource "aws_launch_template" "nginx_pub_2a" {
  name_prefix   = "VEC-PRD-VPC-NGINX-PUB-2A"
  image_id      = var.ami_id
  instance_type = "t2.micro"
  key_name      = var.key_name

  network_interfaces {
    subnet_id         = var.nginx_pub_2a_subnet
    security_groups   = [var.nginx_security_group]
    associate_public_ip_address = true
  }
}

resource "aws_launch_template" "nginx_pub_2c" {
  name_prefix   = "VEC-PRD-VPC-NGINX-PUB-2C"
  image_id      = var.ami_id
  instance_type = "t2.micro"
  key_name      = var.key_name

  network_interfaces {
    subnet_id         = var.nginx_pub_2c_subnet
    security_groups   = [var.nginx_security_group]
    associate_public_ip_address = true
  }
}

resource "aws_launch_template" "tomcat_pri_2a" {
  name_prefix   = "VEC-PRD-VPC-TOMCAT-PRI-2A"
  image_id      = var.ami_id
  instance_type = "t2.micro"
  key_name      = var.key_name

  network_interfaces {
    subnet_id         = var.tomcat_pri_2a_subnet
    security_groups   = [var.tomcat_security_group]
    associate_public_ip_address = false
  }
}

resource "aws_launch_template" "tomcat_pri_2c" {
  name_prefix   = "VEC-PRD-VPC-TOMCAT-PRI-2C"
  image_id      = var.ami_id
  instance_type = "t2.micro"
  key_name      = var.key_name

  network_interfaces {
    subnet_id         = var.tomcat_pri_2c_subnet
    security_groups   = [var.tomcat_security_group]
    associate_public_ip_address = false
  }
}

resource "aws_launch_template" "db_pri_2a" {
  name_prefix   = "VEC-PRD-VPC-DB-PRI-2A"
  image_id      = var.ami_id
  instance_type = "t2.micro"
  key_name      = var.key_name

  network_interfaces {
    subnet_id         = var.db_pri_2a_subnet
    security_groups   = [var.db_security_group]
    associate_public_ip_address = true
  }
}

resource "aws_launch_template" "db_pri_2c" {
  name_prefix   = "VEC-PRD-VPC-DB-PRI-2C"
  image_id      = var.ami_id
  instance_type = "t2.micro"
  key_name      = var.key_name

  network_interfaces {
    subnet_id         = var.db_pri_2c_subnet
    security_groups   = [var.db_security_group]
    associate_public_ip_address = true
  }
}

modules/launch_template/variables.tf

variable "region" {
  description = "The AWS region to create resources in."
  type        = string
}

variable "ami_id" {
  description = "The ID of the AMI to use for the launch templates."
  type        = string
}

variable "key_name" {
  description = "The key pair to use for the instances."
  type        = string
}

variable "nginx_pub_2a_subnet" {
  description = "The ID of the NGINX public subnet in ap-northeast-2a."
  type        = string
}

variable "nginx_pub_2c_subnet" {
  description = "The ID of the NGINX public subnet in ap-northeast-2c."
  type        = string
}

variable "tomcat_pri_2a_subnet" {
  description = "The ID of the TOMCAT private subnet in ap-northeast-2a."
  type        = string
}

variable "tomcat_pri_2c_subnet" {
  description = "The ID of the TOMCAT private subnet in ap-northeast-2c."
  type        = string
}

variable "db_pri_2a_subnet" {
  description = "The ID of the DB private subnet in ap-northeast-2a."
  type        = string
}

variable "db_pri_2c_subnet" {
  description = "The ID of the DB private subnet in ap-northeast-2c."
  type        = string
}

variable "nginx_security_group" {
  description = "The security group ID for the NGINX instances."
  type        = string
}

variable "tomcat_security_group" {
  description = "The security group ID for the TOMCAT instances."
  type        = string
}

variable "db_security_group" {
  description = "The security group ID for the DB instances."
  type        = string
}

modules/launch_template/outputs.tf


output "nginx_pub_2a_id" {
  value = aws_launch_template.nginx_pub_2a.id
}

output "nginx_pub_2c_id" {
  value = aws_launch_template.nginx_pub_2c.id
}

output "tomcat_pri_2a_id" {
  value = aws_launch_template.tomcat_pri_2a.id
}

output "tomcat_pri_2c_id" {
  value = aws_launch_template.tomcat_pri_2c.id
}

output "db_pri_2a_id" {
  value = aws_launch_template.db_pri_2a.id
}

output "db_pri_2c_id" {
  value = aws_launch_template.db_pri_2c.id
}

설명

  • 이 구성을 통해 시작 템플릿을 생성할 수 있습니다.

  • 각 템플릿은 지정된 VPC와 서브넷, 보안 그룹을 사용하며, 퍼블릭 IP 활성화 여부를 설정할 수 있습니다.


오토스케일링 생성

  • 오토스케일링 생성 ( 생성해둔 시작 템플릿과 VPC 이용 )

    • 오토 스케일링 그룹 이름: VEC-PRD-VPC-NGINX-PUB-2A
      생성한 시작 템플릿 지정: VEC-PRD-VPC-NGINX-PUB-2A
      네트워크 설정: 생성해둔 VPC 선택 (vec-prd-vpc : 10.250.0.0/16)
      서브넷: VEC-PRD-VPC-NGINX-PUB-2A
      로드 밸런서(기존) 대상 그룹에서 선택: VEC-PRD-NGINX-GROUP
      그룹 크기를 설정합니다.
      초기 인스턴스 수: 1, 최소 인스턴스 수: 1, 최대 인스턴스 수: 3를 설정합니다.

    • 오토 스케일링 그룹 이름: VEC-PRD-VPC-NGINX-PUB-2C
      생성한 시작 템플릿 지정:
      네트워크 설정: 생성해둔 VPC 선택 (vec-prd-vpc : 10.250.0.0/16)
      서브넷: VEC-PRD-VPC-NGINX-PUB-2C
      로드 밸런서(기존) 대상 그룹에서 선택: VEC-PRD-NGINX-GROUP
      그룹 크기를 설정합니다.
      초기 인스턴스 수: 1, 최소 인스턴스 수: 1, 최대 인스턴스 수: 3를 설정합니다.

    • 오토 스케일링 그룹 이름: VEC-PRD-VPC-TOMCAT-PRI-2A
      생성한 시작 템플릿 지정:
      네트워크 설정: 생성해둔 VPC 선택 (vec-prd-vpc : 10.250.0.0/16)
      서브넷: VEC-PRD-VPC-TOMCAT-PRI-2A
      로드 밸런서(기존) 대상 그룹에서 선택: VEC-PRD-VPC-TOMCAT-GROUP
      그룹 크기를 설정합니다.
      초기 인스턴스 수: 1, 최소 인스턴스 수: 1, 최대 인스턴스 수: 3를 설정합니다.

    • 오토 스케일링 그룹 이름: VEC-PRD-VPC-TOMCAT-PRI-2C
      생성한 시작 템플릿 지정:
      네트워크 설정: 생성해둔 VPC 선택 (vec-prd-vpc : 10.250.0.0/16)
      서브넷: VEC-PRD-VPC-TOMCAT-PRI-2C
      로드 밸런서(기존) 대상 그룹에서 선택: VEC-PRD-VPC-TOMCAT-GROUP
      그룹 크기를 설정합니다.
      초기 인스턴스 수: 1, 최소 인스턴스 수: 1, 최대 인스턴스 수: 3를 설정합니다.

    • 오토 스케일링 그룹 이름: VEC-PRD-VPC-DB-PRI-2A
      생성한 시작 템플릿 지정:
      네트워크 설정: 생성해둔 VPC 선택 (vec-prd-vpc : 10.250.0.0/16)
      서브넷: VEC-PRD-VPC-DB-PRI-2A
      로드 밸런서 없이 생성
      그룹 크기를 설정합니다.
      초기 인스턴스 수: 1, 최소 인스턴스 수: 1, 최대 인스턴스 수: 3를 설정합니다.

    • 오토 스케일링 그룹 이름: VEC-PRD-VPC-DB-PRI-2C
      생성한 시작 템플릿 지정:
      네트워크 설정: 생성해둔 VPC 선택 (vec-prd-vpc : 10.250.0.0/16)
      서브넷: VEC-PRD-VPC-DB-PRI-2C
      로드 밸런서 없이 생성
      그룹 크기를 설정합니다.
      초기 인스턴스 수: 1, 최소 인스턴스 수: 1, 최대 인스턴스 수: 3를 설정합니다.

    • 스케일링 정책( 통일 )을 설정합니다.
      "Target tracking scaling policy"를 선택하고, 예를 들어 CPU 사용률을 기준으로 정책을 설정합니다.
      목표를 예를 들어 "50%"로 설정하여, 평균 CPU 사용률이 50%를 초과하면 인스턴스를 추가하고, 50% 이하로 떨어지면 인스턴스를 제거하는 방식으로 구성합니다.

  • 오토스케일링 각각에 인스턴스 종료시 알람 설정 ( 9회차 참고 )

modules/autoscaling/main.tf 는 파일 참고

modules/autoscaling/variables.tf


variable "region" {
  description = "The AWS region to create resources in."
  type        = string
}

variable "nginx_pub_2a_launch_template_id" {
  description = "The ID of the NGINX public 2A launch template."
  type        = string
}

variable "nginx_pub_2c_launch_template_id" {
  description = "The ID of the NGINX public 2C launch template."
  type        = string
}

variable "tomcat_pri_2a_launch_template_id" {
  description = "The ID of the TOMCAT private 2A launch template."
  type        = string
}

variable "tomcat_pri_2c_launch_template_id" {
  description = "The ID of the TOMCAT private 2C launch template."
  type        = string
}

variable "db_pri_2a_launch_template_id" {
  description = "The ID of the DB private 2A launch template."
  type        = string
}

variable "db_pri_2c_launch_template_id" {
  description = "The ID of the DB private 2C launch template."
  type        = string
}

variable "nginx_pub_2a_subnet" {
  description = "The ID of the NGINX public 2A subnet."
  type        = string
}

variable "nginx_pub_2c_subnet" {
  description = "The ID of the NGINX public 2C subnet."
  type        = string
}

variable "tomcat_pri_2a_subnet" {
  description = "The ID of the TOMCAT private 2A subnet."
  type        = string
}

variable "tomcat_pri_2c_subnet" {
  description = "The ID of the TOMCAT private 2C subnet."
  type        = string
}

variable "db_pri_2a_subnet" {
  description = "The ID of the DB private 2A subnet."
  type        = string
}

variable "db_pri_2c_subnet" {
  description = "The ID of the DB private 2C subnet."
  type        = string
}

variable "nginx_target_group_arn" {
  description = "The ARN of the NGINX target group."
  type        = string
}

variable "tomcat_target_group_arn" {
  description = "The ARN of the TOMCAT target group."
  type        = string
}


오토스케일링을 통해 인스턴스 종료시 알람 설정 ( 9회차 참고 )

  • sns 생성, 구독 추가

modules/notification/main.tf

provider "aws" {
  region = var.region
}

resource "aws_sns_topic" "nginx_pub_2a" {
  name = "NGINX-PUB-2A-TerminateInstanceNotifications"
}

resource "aws_sns_topic" "nginx_pub_2c" {
  name = "NGINX-PUB-2C-TerminateInstanceNotifications"
}

resource "aws_sns_topic" "tomcat_pri_2a" {
  name = "TOMCAT-PRI-2A-TerminateInstanceNotifications"
}

resource "aws_sns_topic" "tomcat_pri_2c" {
  name = "TOMCAT-PRI-2C-TerminateInstanceNotifications"
}

resource "aws_sns_topic" "db_pri_2a" {
  name = "DB-PRI-2A-TerminateInstanceNotifications"
}

resource "aws_sns_topic" "db_pri_2c" {
  name = "DB-PRI-2C-TerminateInstanceNotifications"
}

resource "aws_sns_topic_subscription" "nginx_pub_2a" {
  topic_arn = aws_sns_topic.nginx_pub_2a.arn
  protocol  = "email"
  endpoint  = "p8489009@gmail.com"
}

resource "aws_sns_topic_subscription" "nginx_pub_2c" {
  topic_arn = aws_sns_topic.nginx_pub_2c.arn
  protocol  = "email"
  endpoint  = "p8489009@gmail.com"
}

resource "aws_sns_topic_subscription" "tomcat_pri_2a" {
  topic_arn = aws_sns_topic.tomcat_pri_2a.arn
  protocol  = "email"
  endpoint  = "p8489009@gmail.com"
}

resource "aws_sns_topic_subscription" "tomcat_pri_2c" {
  topic_arn = aws_sns_topic.tomcat_pri_2c.arn
  protocol  = "email"
  endpoint  = "p8489009@gmail.com"
}

resource "aws_sns_topic_subscription" "db_pri_2a" {
  topic_arn = aws_sns_topic.db_pri_2a.arn
  protocol  = "email"
  endpoint  = "p8489009@gmail.com"
}

resource "aws_sns_topic_subscription" "db_pri_2c" {
  topic_arn = aws_sns_topic.db_pri_2c.arn
  protocol  = "email"
  endpoint  = "p8489009@gmail.com"
}

modules/notification/variables.tf

variable "region" {
  description = "The AWS region to create resources in"
  type        = string
}

variable "email_endpoint" {
  description = "The email address to subscribe to the SNS topic"
  type        = string
  default     = "p8489009@gmail.com"
}

modules/notification/outputs.tf

output "nginx_pub_2a_arn" {
  value = aws_sns_topic.nginx_pub_2a.arn
}

output "nginx_pub_2c_arn" {
  value = aws_sns_topic.nginx_pub_2c.arn
}

output "tomcat_pri_2a_arn" {
  value = aws_sns_topic.tomcat_pri_2a.arn
}

output "tomcat_pri_2c_arn" {
  value = aws_sns_topic.tomcat_pri_2c.arn
}

output "db_pri_2a_arn" {
  value = aws_sns_topic.db_pri_2a.arn
}

output "db_pri_2c_arn" {
  value = aws_sns_topic.db_pri_2c.arn
}

modules/cloudwatch_alarms/main.tf


variable "nginx_pub_2a_arn" {
  description = "ARN for NGINX-PUB-2A notifications"
  type        = string
}

variable "nginx_pub_2c_arn" {
  description = "ARN for NGINX-PUB-2C notifications"
  type        = string
}

variable "tomcat_pri_2a_arn" {
  description = "ARN for TOMCAT-PRI-2A notifications"
  type        = string
}

variable "tomcat_pri_2c_arn" {
  description = "ARN for TOMCAT-PRI-2C notifications"
  type        = string
}

variable "db_pri_2a_arn" {
  description = "ARN for DB-PRI-2A notifications"
  type        = string
}

variable "db_pri_2c_arn" {
  description = "ARN for DB-PRI-2C notifications"
  type        = string
}

resource "aws_cloudwatch_metric_alarm" "NGINX-PUB-2A-TerminateInstanceAlarm" {
  alarm_name          = "NGINX-PUB-2A-TerminateInstanceAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "GroupTerminatingInstances"
  namespace           = "AWS/AutoScaling"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "This metric monitors the terminating instances in NGINX-PUB-2A"
  actions_enabled     = true
  alarm_actions       = [var.nginx_pub_2a_arn]
  dimensions = {
    AutoScalingGroupName = "VEC-PRD-VPC-NGINX-PUB-2A"
  }
}

resource "aws_cloudwatch_metric_alarm" "NGINX-PUB-2C-TerminateInstanceAlarm" {
  alarm_name          = "NGINX-PUB-2C-TerminateInstanceAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "GroupTerminatingInstances"
  namespace           = "AWS/AutoScaling"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "This metric monitors the terminating instances in NGINX-PUB-2C"
  actions_enabled     = true
  alarm_actions       = [var.nginx_pub_2c_arn]
  dimensions = {
    AutoScalingGroupName = "VEC-PRD-VPC-NGINX-PUB-2C"
  }
}

resource "aws_cloudwatch_metric_alarm" "TOMCAT-PRI-2A-TerminateInstanceAlarm" {
  alarm_name          = "TOMCAT-PRI-2A-TerminateInstanceAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "GroupTerminatingInstances"
  namespace           = "AWS/AutoScaling"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "This metric monitors the terminating instances in TOMCAT-PRI-2A"
  actions_enabled     = true
  alarm_actions       = [var.tomcat_pri_2a_arn]
  dimensions = {
    AutoScalingGroupName = "VEC-PRD-VPC-TOMCAT-PRI-2A"
  }
}

resource "aws_cloudwatch_metric_alarm" "TOMCAT-PRI-2C-TerminateInstanceAlarm" {
  alarm_name          = "TOMCAT-PRI-2C-TerminateInstanceAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "GroupTerminatingInstances"
  namespace           = "AWS/AutoScaling"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "This metric monitors the terminating instances in TOMCAT-PRI-2C"
  actions_enabled     = true
  alarm_actions       = [var.tomcat_pri_2c_arn]
  dimensions = {
    AutoScalingGroupName = "VEC-PRD-VPC-TOMCAT-PRI-2C"
  }
}

resource "aws_cloudwatch_metric_alarm" "DB-PRI-2A-TerminateInstanceAlarm" {
  alarm_name          = "DB-PRI-2A-TerminateInstanceAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "GroupTerminatingInstances"
  namespace           = "AWS/AutoScaling"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "This metric monitors the terminating instances in DB-PRI-2A"
  actions_enabled     = true
  alarm_actions       = [var.db_pri_2a_arn]
  dimensions = {
    AutoScalingGroupName = "VEC-PRD-VPC-DB-PRI-2A"
  }
}

resource "aws_cloudwatch_metric_alarm" "DB-PRI-2C-TerminateInstanceAlarm" {
  alarm_name          = "DB-PRI-2C-TerminateInstanceAlarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "GroupTerminatingInstances"
  namespace           = "AWS/AutoScaling"
  period              = "300"
  statistic           = "Sum"
  threshold           = "0"
  alarm_description   = "This metric monitors the terminating instances in DB-PRI-2C"
  actions_enabled     = true
  alarm_actions       = [var.db_pri_2c_arn]
  dimensions = {
    AutoScalingGroupName = "VEC-PRD-VPC-DB-PRI-2C"
  }
}

modules/cloudwatch_alarms/variables.tf

variable "region" {
  description = "The AWS region to create resources in"
  type        = string
}

variable "email_endpoint" {
  description = "The email address to subscribe to the SNS topic"
  type        = string
  default     = "p8489009@gmail.com"
}

ALB를 통해 오토 스케일링 진행 시 WAF를 사용하여 보안 향상 ( 11회차 참고 )

modules/waf/main.tf

provider "aws" {
  region = var.region
}

resource "aws_wafv2_web_acl" "nginx_web_acl" {
  name        = "NGINX-WebACL"
  scope       = "REGIONAL"
  description = "NGINX Web ACL"
  default_action {
    allow {}
  }
  visibility_config {
    sampled_requests_enabled = true
    cloudwatch_metrics_enabled = true
    metric_name = "nginxWebACL"
  }
  rule {
    name     = "AWSManagedRulesSQLiRuleSet"
    priority = 1
    override_action {
      count {}
    }
    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesSQLiRuleSet"
      }
    }
    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name = "AWSManagedRulesSQLiRuleSet"
    }
  }
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 2
    override_action {
      count {}
    }
    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesCommonRuleSet"
      }
    }
    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name = "AWSManagedRulesCommonRuleSet"
    }
  }
}

resource "aws_wafv2_web_acl_association" "nginx" {
  resource_arn = var.nginx_alb_arn
  web_acl_arn  = aws_wafv2_web_acl.nginx_web_acl.arn
}

resource "aws_wafv2_web_acl" "tomcat_web_acl" {
  name        = "TOMCAT-WebACL"
  scope       = "REGIONAL"
  description = "TOMCAT Web ACL"
  default_action {
    allow {}
  }
  visibility_config {
    sampled_requests_enabled = true
    cloudwatch_metrics_enabled = true
    metric_name = "tomcatWebACL"
  }
  rule {
    name     = "AWSManagedRulesSQLiRuleSet"
    priority = 1
    override_action {
      count {}
    }
    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesSQLiRuleSet"
      }
    }
    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name = "AWSManagedRulesSQLiRuleSet"
    }
  }
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 2
    override_action {
      count {}
    }
    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "AWSManagedRulesCommonRuleSet"
      }
    }
    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name = "AWSManagedRulesCommonRuleSet"
    }
  }
}

resource "aws_wafv2_web_acl_association" "tomcat" {
  resource_arn = var.tomcat_alb_arn
  web_acl_arn  = aws_wafv2_web_acl.tomcat_web_acl.arn
}


modules/waf/variables.tf

variable "region" {
  description = "The region where resources will be created"
  type        = string
}

variable "nginx_alb_arn" {
  description = "The ARN of the NGINX ALB to associate with WAF"
  type        = string
}

variable "tomcat_alb_arn" {
  description = "The ARN of the TOMCAT ALB to associate with WAF"
  type        = string
}

terraform 구성 rule

  • SQL database managed rule group
    VendorName: AWS, Name: AWSManagedRulesSQLiRuleSet, WCU: 200
  • Core rule set (CRS) managed rule group
    VendorName: AWS, Name: AWSManagedRulesCommonRuleSet, WCU: 700

나머지 terraform 수행

  • waflogging-s3
    ec2 bastion 실행

    • 파일 참고

0개의 댓글