[Sprint] Terraform x AWS

# 학습 목표

Terraform을 이용한 AWS 아키텍처 구성


# 해결 과제

다음의 아키텍처를 terraform을 이용해 작성합니다.

STEP 1: 자습서: DB 인스턴스에 사용할 Amazon VPC 생성

  1. VPC 및 서브넷 생성
  2. VPC 보안 그룹 생성
  3. DB 서브넷 그룹 생성

STEP 2: EC2 인스턴스 생성

만들어야 하는 사양은 다음과 같습니다.

  • AMI: Ubuntu Server 18
  • 인스턴스 타입: t2.micro
  • 사용자 데이터
  • 키 페어: 수동으로 만들고 EC2에 할당합니다.

Advanced Challenges

STEP 3: 자습서: DB 인스턴스 생성

  • 자습서에 표시된 사양대로 RDS 인스턴스를 생성합니다.

STEP 4: 애플리케이션 로드 밸런서 및 Auto Scaling Group 적용

  • Auto Scaling Group은 최소 2개, 최대 10개로 설정해 놓습니다.

# 실습 자료

sprint-iac-terraform


# 과제 항목별 진행 상황

단일 파일로 구성한 예

### terraform block ###
terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.35"
    }
  }
}
### provider block ###
provider "aws" {
  region = "ap-northeast-2"

  default_tags {
    tags = {
      name = "tf-sprint"
    }
  }
}
## aws_availability_zones 지정
## ap-northeast-2b,d 제외 t2.micro intancetype을 사용하기 위함
data "aws_availability_zones" "available" {
  state = "available"
  exclude_names = ["ap-northeast-2b", "ap-northeast-2d"]
}
## VPC 구성을 module로 정의
## module 을 구문에 삽입 후 terraform init 을 하게 되면
## 자동으로 module이 .terraform 폴더로 pull이 된다.
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "4.0.1"

  name = "tf-vpc"
  cidr = "10.0.0.0/16"

  azs                  = data.aws_availability_zones.available.names
  public_subnets       = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnets      = ["10.0.3.0/24", "10.0.4.0/24"]
  enable_dns_hostnames = true
  enable_dns_support   = true
  enable_nat_gateway = true
}
## EC2 AMI 정의 ubuntu로 설정
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20230424"]
  }
}
## EC2 Instance 템플릿 정의
resource "aws_launch_template" "tf-ec2" {
  
  name_prefix     = "tf-sprint-ec2-"
  image_id        = data.aws_ami.ubuntu.id
  instance_type   = "t2.micro"
  user_data       = "${base64encode(<<-EOF
    #!/bin/bash    
    sudo apt update -y;sudo apt install -y mysql-client-core-5.7
    echo '<h1>Terraform Apply Complete</h1>' > index.html
    echo '<b>SHOW DATABASES</b><p style="color:red; white-space:pre;">' >> index.html
    MYSQL_PWD="${aws_db_instance.tfRDS.password}" mysql -h '${aws_db_instance.tfRDS.address}' -u '${aws_db_instance.tfRDS.username}' -e 'show databases' >> index.html
    echo '</p><h1>DB Access Complete</h1>' >> index.html
    sudo nohup busybox httpd -f -p 80 &
  EOF
  )}"
  key_name = "PCKEC2"
  network_interfaces {
  associate_public_ip_address = true
  security_groups = [aws_security_group.tfEC2sg.id]
  }
}
## Autoscaling Group 정의
resource "aws_autoscaling_group" "tfASG" {
  name                 = "tfASG"
  min_size             = 2
  max_size             = 10
  desired_capacity     = 2
  launch_template {
    id      = aws_launch_template.tf-ec2.id
  }
  vpc_zone_identifier  = module.vpc.public_subnets

  tag {
    key                 = "Name"
    value               = "Terraform X AWS - ASG"
    propagate_at_launch = true
    #(필수)이 ASG를 통해 시작된 Amazon EC2 인스턴스에 태그를 전파
    #EC2 Deploy 할때마다 해당 태그가 설정됨
  }
}
## Application Load Balancer
resource "aws_lb" "tfALB" {
  name               = "tfALB"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.tfALBsg.id,]
  subnets            = module.vpc.public_subnets
}
## ALB Listener
resource "aws_lb_listener" "tfALBListener" {
  load_balancer_arn = aws_lb.tfALB.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.tfALBtg.arn
  }
}
## ALB target group
resource "aws_lb_target_group" "tfALBtg" {
  name     = "Terraform-ALB-TargetGroup"
  port     = 80
  protocol = "HTTP"
  vpc_id   = module.vpc.vpc_id
}

## Register targetgroup and Include as pending below
resource "aws_autoscaling_attachment" "tfASGattach" {
  autoscaling_group_name = aws_autoscaling_group.tfASG.id
  alb_target_group_arn   = aws_lb_target_group.tfALBtg.arn
}

### Security Group Create ###
resource "aws_security_group" "tfEC2sg" {
  name = "Terraform-EC2-HTTP,SSH-Access"
  ingress {
    from_port       = 80
    to_port         = 80
    protocol        = "tcp"
    security_groups = [aws_security_group.tfALBsg.id]
    #ALB 보안그룹(tfALBsg)으로 들어온 트래픽만 허용
  }

  ingress {
    from_port       = 22
    to_port         = 22
    protocol        = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  vpc_id = module.vpc.vpc_id
}
# IP 프로토콜 번호 "-1"은 일반적으로 "모든 프로토콜" 또는 "전체"를 의미
# "-1"로 설정된 경우, IP 패킷은 모든 프로토콜을 지원하는 것을 의미
resource "aws_security_group" "tfALBsg" {
  name = "Terraform-ALB-HTTP-Access"
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  vpc_id = module.vpc.vpc_id
}

resource "aws_security_group" "tfRDSsg" {
  name        = "tf_RDS_sg"
  vpc_id      = module.vpc.vpc_id

  ingress {
    from_port   = 3306
    to_port     = 3306
    protocol    = "TCP"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

##DataBase Instance 생성 정의
resource "aws_db_instance" "tfRDS" {
  identifier             = "mydb01"
  allocated_storage      = "10"
  engine                 = "mysql"
  engine_version         = "8.0.32"
  instance_class         = "db.t2.micro"
  db_name                = "terraformRDS"
  username               = "root"
  password               = "toor0515"
  vpc_security_group_ids = [aws_security_group.tfRDSsg.id]
  db_subnet_group_name   = aws_db_subnet_group.tfRDSsubnets.id
  skip_final_snapshot  = true
}

resource "aws_db_subnet_group" "tfRDSsubnets" {
  name        = "terraform-rds-subnet-group"
  subnet_ids  = module.vpc.private_subnets
}

로드 밸런스 DNS 로 접속 결과 메인 파일 안에 쉘 스크립트를 삽입하여 EC2에서 RDS로 접속이 가능한지 자동으로 확인

# 위의 main.tf 코드 참고 아래는 정확한 변수명을 생략하였으며
# 스크립트 실행을 하면서 index.html 파일로 값이 어떻게 들어가는지 보여줌
#!/bin/bash    
sudo apt update -y
sudo apt install -y mysql-client-core-5.7
echo '<h1>Terraform Apply Complete</h1>' > index.html
echo '<b>SHOW DATABASES</b><p style="color:red; white-space:pre;">' >> index.html
MYSQL_PWD="${[DB_password]}" mysql -h [RDS_Endpoint] -u '[username]' -e 'show databases' >> index.html
echo '</p><h1>DB Access Complete</h1>' >> index.html
sudo nohup busybox httpd -f -p 80 &

user_data       = "${base64encode(<<-EOF
    #!/bin/bash    
    sudo apt update -y;sudo apt install -y mysql-client-core-5.7
    echo '<h1>Terraform Apply Complete</h1>' > index.html
    echo '<b>SHOW DATABASES</b><p style="color:red; white-space:pre;">' >> index.html
    MYSQL_PWD="${aws_db_instance.tfRDS.password}" mysql -h '${aws_db_instance.tfRDS.address}' -u '${aws_db_instance.tfRDS.username}' -e 'show databases' >> index.html
    echo '</p><h1>DB Access Complete</h1>' >> index.html
    sudo nohup busybox httpd -f -p 80 &
  EOF
  )}"
<--! index.html -->
<h1>Terraform Apply Complete</h1>
<b>SHOW DATABASES</b><p style="color:red; white-space:pre;">
<--! 쿼리 결과  -->
Database
information_schema
mysql
performance_schema
sys
terraformRDS
</p><h1>DB Access Complete</h1>

모듈 단위로 구성한 예

모듈 구조

1. vpc

main.tf

terraform {
  # Location of vpc state file
  backend "s3" {
    bucket  = "bighead-tfstate"
    key     = "VPC/terraform.tfstate"
    region  = "ap-northeast-2"
    encrypt = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "ap-northeast-2"
}

vpc.tf

# Main VPC
resource "aws_vpc" "main_vpc" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "main_vpc"
  }
}

subnet.tf

# Public Subnet - AZ(a)
resource "aws_subnet" "web_pub_subnet_a" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "WEB-Pub-subnet-a"
  }
}

# Private Subnet - AZ(a)
resource "aws_subnet" "rds_pvt_subnet_a" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "RDS-Pvt-subnet-a"
  }
}

# Public Subnet - AZ(c)
resource "aws_subnet" "web_pub_subnet_c" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.3.0/24"
  availability_zone = "ap-northeast-2c"

  tags = {
    Name = "WEB-Pub-subnet-c"
  }
}

# Private Subnet - AZ(c)
resource "aws_subnet" "rds_pvt_subnet_c" {
  vpc_id            = aws_vpc.main_vpc.id
  cidr_block        = "10.0.4.0/24"
  availability_zone = "ap-northeast-2c"

  tags = {
    Name = "RDS-Pvt-subnet-c"
  }
}

# RDS Subnet Group
# Private Subnet - AZ(a,c)
resource "aws_db_subnet_group" "rds_subnet_group" {
  name       = "rds_subnet_group"
  subnet_ids = [aws_subnet.rds_pvt_subnet_a.id, aws_subnet.rds_pvt_subnet_c.id]

  tags = {
    Name = "RDS-subnet-group"
  }
}

route-table.tf

# Public Route Table - Internet Gateway
resource "aws_route_table" "pub_route_table" {
  vpc_id = aws_vpc.main_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main_igw.id
  }

  tags = {
    Name = "Pub-route-table"
  }
}

# Private Route Table - NAT Gateway
resource "aws_route_table" "pvt_route_table" {
  vpc_id = aws_vpc.main_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.main_ngw.id
  }

  tags = {
    Name = "Pvt-route-table"
  }
}

# Public Route Table Association - Public Subnet - AZ(a)
resource "aws_route_table_association" "pub_route_table_association_a" {
  subnet_id      = aws_subnet.web_pub_subnet_a.id
  route_table_id = aws_route_table.pub_route_table.id
}

# Public Route Table Association - Public Subnet - AZ(c)
resource "aws_route_table_association" "pub_route_table_association_c" {
  subnet_id      = aws_subnet.web_pub_subnet_c.id
  route_table_id = aws_route_table.pub_route_table.id
}

# Private Route Table Association - Private Subnet - AZ(a)
resource "aws_route_table_association" "pvt_route_table_association_a" {
  subnet_id      = aws_subnet.rds_pvt_subnet_a.id
  route_table_id = aws_route_table.pvt_route_table.id
}

# Private Route Table Association - Private Subnet - AZ(c)
resource "aws_route_table_association" "pvt_route_table_association_c" {
  subnet_id      = aws_subnet.rds_pvt_subnet_c.id
  route_table_id = aws_route_table.pvt_route_table.id
}

gateway.tf

# Internet Gateway
resource "aws_internet_gateway" "main_igw" {
  vpc_id = aws_vpc.main_vpc.id

  tags = {
    Name = "main-igw"
  }
}

# NAT Gateway
resource "aws_nat_gateway" "main_ngw" {
  allocation_id = aws_eip.ngw_eip.id
  subnet_id     = aws_subnet.web_pub_subnet_c.id

  tags = {
    Name = "main-ngw"
  }
}

security-group.tf

# Web Server Security Group
resource "aws_security_group" "web_security_group" {
  name        = "web-security-group"
  description = "Web Server Security Group"
  vpc_id      = aws_vpc.main_vpc.id

  tags = {
    Name = "web-security-group"
  }
}

# RDB Server Security Group
resource "aws_security_group" "rds_security_group" {
  name        = "rds-security-group"
  description = "RDB Server Security Group"
  vpc_id      = aws_vpc.main_vpc.id

  tags = {
    Name = "rds-security-group"
  }
}

# ALB Security Group
resource "aws_security_group" "alb_security_group" {
  name        = "alb-security-group"
  description = "ALB Security Group"
  vpc_id      = aws_vpc.main_vpc.id

  tags = {
    Name = "alb-security-group"
  }
}

# Web Server Security Group Ingress
# 80 port
resource "aws_vpc_security_group_ingress_rule" "web_security_group_ingress_http" {
  security_group_id = aws_security_group.web_security_group.id

  cidr_ipv4   = "0.0.0.0/0"
  from_port   = 80
  to_port     = 80
  ip_protocol = "tcp"
}

# Web Server Security Group Ingress
# 22 port
resource "aws_vpc_security_group_ingress_rule" "web_security_group_ingress_ssh" {
  security_group_id = aws_security_group.web_security_group.id

  cidr_ipv4   = "0.0.0.0/0"
  from_port   = 22
  to_port     = 22
  ip_protocol = "tcp"
}

# Web Server Security Group Egress
# Any
resource "aws_vpc_security_group_egress_rule" "web_security_group_egress" {
  security_group_id = aws_security_group.web_security_group.id

  cidr_ipv4   = "0.0.0.0/0"
  ip_protocol = -1
}

# RDB Server Security Group Ingress
# 3306 port
resource "aws_vpc_security_group_ingress_rule" "rds_security_group_ingress" {
  security_group_id = aws_security_group.rds_security_group.id

  referenced_security_group_id = aws_security_group.web_security_group.id
  from_port                    = 3306
  to_port                      = 3306
  ip_protocol                  = "tcp"
}

# RDB Server Security Group Egress
# Any
resource "aws_vpc_security_group_egress_rule" "rds_security_group_egress" {
  security_group_id = aws_security_group.rds_security_group.id

  cidr_ipv4   = "0.0.0.0/0"
  ip_protocol = -1
}

# ALB Security Group Ingress
# 80 port
resource "aws_vpc_security_group_ingress_rule" "alb_security_group_ingress_http" {
  security_group_id = aws_security_group.alb_security_group.id

  cidr_ipv4   = "0.0.0.0/0"
  from_port   = 80
  to_port     = 80
  ip_protocol = "tcp"
}

# ALB Security Group Egress
# Any
resource "aws_vpc_security_group_egress_rule" "alb_security_group_egress" {
  security_group_id = aws_security_group.alb_security_group.id

  cidr_ipv4   = "0.0.0.0/0"
  ip_protocol = -1
}

eip.tf

# EIP of NAT Gateway
resource "aws_eip" "ngw_eip" {
  vpc = true
}

outputs.tf

# Main VPC ID
output "vpc_id" {
  description = "ID of the Main VPC"
  value       = aws_vpc.main_vpc.id
}

# Public Subnet ID - AZ(a)
output "subnet_pub_a_id" {
  description = "ID of the WEB-Pub-subnet-a"
  value       = aws_subnet.web_pub_subnet_a.id
}

# Private Subnet ID - AZ(a)
output "subnet_pvt_a_id" {
  description = "ID of the RDS-Pvt-subnet-a"
  value       = aws_subnet.rds_pvt_subnet_a.id
}

# Public Subnet ID - AZ(c)
output "subnet_pub_c_id" {
  description = "ID of the WEB-Pub-subnet-c"
  value       = aws_subnet.web_pub_subnet_c.id
}

# Private Subnet ID - AZ(c)
output "subnet_pvt_c_id" {
  description = "ID of the RDS-Pvt-subnet-c"
  value       = aws_subnet.rds_pvt_subnet_c.id
}

# RDS Subnet Group Name
output "subnet_group_rds_name" {
  description = "Name of the RDS-subnet-group"
  value       = aws_db_subnet_group.rds_subnet_group.name
}

# Web Server Security Group ID
output "web_security_group_id" {
  description = "ID of the Web Server Security Group"
  value       = aws_security_group.web_security_group.id
}

# RDB Server Security Group ID
output "rds_security_group_id" {
  description = "ID of the RDB Server Security Group"
  value       = aws_security_group.rds_security_group.id
}

# ALB Security Group ID
output "alb_security_group_id" {
  description = "ID of the Application Load Balancer Security Group"
  value       = aws_security_group.alb_security_group.id
}

2. ec2

main.tf

terraform {
  # Location of ec2 state file
  backend "s3" {
    bucket  = "bighead-tfstate"
    key     = "EC2/terraform.tfstate"
    region  = "ap-northeast-2"
    encrypt = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "ap-northeast-2"
}

data.tf

# Remote State of VPC
data "terraform_remote_state" "vpc" {
  backend = "s3"
  config = {
    bucket = "bighead-tfstate"
    key    = "VPC/terraform.tfstate"
    region = "ap-northeast-2"
  }
}

variables.tf

# Web Server Port
variable "server_port" {
  description = "Server Port of the Web Server"
  type        = number
  default     = 80
}

ec2.tf

# EC2 Instance - Web Server
resource "aws_instance" "web_server" {
  ami                         = "ami-017c15d9ff8294f00"
  instance_type               = "t2.micro"
  subnet_id                   = data.terraform_remote_state.vpc.outputs.subnet_pub_c_id
  availability_zone           = "ap-northeast-2c"
  vpc_security_group_ids      = [data.terraform_remote_state.vpc.outputs.web_security_group_id]
  associate_public_ip_address = true  # Associate a public IP address
  key_name                    = "my-instance-key-pair"

  # Start httpd Web Server
  user_data                   = <<-EOF
    #!/bin/bash    
    echo "Hello, World" > index.html
    sudo nohup busybox httpd -f -p ${var.server_port} &
  EOF

  tags = {
    Name = "bighead-webserver"
  }
}

alb.tf

# Application Load Balancer - Web Server
resource "aws_lb" "web_server_alb" {
  name               = "bighead-webserver-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [data.terraform_remote_state.vpc.outputs.alb_security_group_id]
  subnets            = [data.terraform_remote_state.vpc.outputs.subnet_pub_a_id, data.terraform_remote_state.vpc.outputs.subnet_pub_c_id]
}

# Target Group for Application Load Balancer
resource "aws_lb_target_group" "web_server_alb_target" {
  name     = "webserver-alb-target"
  port     = 80
  protocol = "HTTP"
  vpc_id   = data.terraform_remote_state.vpc.outputs.vpc_id
}

# Listener for Application Load Balancer
resource "aws_lb_listener" "web_server_alb_listener" {
  load_balancer_arn = aws_lb.web_server_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web_server_alb_target.id
  }
}

autoscaling.tf

# Launch Template - Web Server
resource "aws_launch_template" "web_server_template" {
  name          = "webserver-template"
  image_id      = "ami-017c15d9ff8294f00"
  instance_type = "t2.micro"
  key_name      = "my-instance-key-pair"

  network_interfaces {
    associate_public_ip_address = true  # Associate a public IP address
    security_groups             = [data.terraform_remote_state.vpc.outputs.web_security_group_id]
  }

  tag_specifications {
    resource_type = "instance"

    tags = {
      Name = "bighead-webserver"
    }
  }
  
  # Start httpd Web Server
  user_data = "${base64encode(<<-EOF
    #!/bin/bash    
    echo "Hello, World" > index.html
    sudo nohup busybox httpd -f -p ${var.server_port} &
  EOF
  )}"
}

# Autoscaling Group - Web Server
resource "aws_autoscaling_group" "web_server_asg" {
  name                = "webserver-autoscaling-group"
  vpc_zone_identifier = [data.terraform_remote_state.vpc.outputs.subnet_pub_a_id, data.terraform_remote_state.vpc.outputs.subnet_pub_c_id]
  desired_capacity    = 2
  max_size            = 10
  min_size            = 2
  target_group_arns   = [aws_lb_target_group.web_server_alb_target.id]

  launch_template {
    id      = aws_launch_template.web_server_template.id
    version = "$Latest"
  }
}

3. rds

main.tf

terraform {
  # Location of rds state file
  backend "s3" {
    bucket  = "bighead-tfstate"
    key     = "RDS/terraform.tfstate"
    region  = "ap-northeast-2"
    encrypt = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "ap-northeast-2"
}

data.tf

# Remote State of VPC
data "terraform_remote_state" "vpc" {
  backend = "s3"
  config = {
    bucket = "bighead-tfstate"
    key    = "VPC/terraform.tfstate"
    region = "ap-northeast-2"
  }
}

rds.tf

# RDS Instance - MySQL
resource "aws_db_instance" "mysql-db" {
  allocated_storage           = 10
  identifier                  = "mysql-bighead"
  db_name                     = "bighead"
  engine                      = "mysql"
  engine_version              = "8.0.28"
  instance_class              = "db.t3.micro"
  username                    = "admin"
  manage_master_user_password = true  # Managing the master password with Secrets Manager
  parameter_group_name        = "default.mysql8.0"
  db_subnet_group_name        = data.terraform_remote_state.vpc.outputs.subnet_group_rds_name
  vpc_security_group_ids      = [data.terraform_remote_state.vpc.outputs.rds_security_group_id]
  skip_final_snapshot         = true
  port                        = 3306
}

# TROUBLE SHOOTING LOG

💡 Autoscaling Group 생성 시 오류 발생 Error: creating Auto Scaling Group (webserver-autoscaling-group): ValidationError: You must use a valid fully-formed launch template. Security group sg-063a69a18d2ceb979 and subnet subnet-0c524365a4ac5a7d9 belong to different networks.

원인

Autoscaling Group 생성 시 availability_zones 옵션을 지정하면, 해당 가용 영역의 기본 서브넷이 Autoscaling Group의 서브넷으로 선택되는데, 해당 서브넷이 Launch Template에 지정되어 있는 보안 그룹의 서브넷과 달라 오류가 발생함.

해결 방안

availability_zones 대신 vpc_zone_identifier 옵션을 사용해, Autoscaling Group에 서브넷을 직접 지정하여 해결

💡 EC2 Public DNS로 SSH 접속 불가

원인

보안그룹에서 소스 대상을 ALB용으로 생성한 보안그룹으로 지정했기 때문

resource "aws_security_group" "tfEC2sg" {
  name = "Terraform-EC2-HTTP,SSH-Access"
  ingress {
    from_port       = 80
    to_port         = 80
    protocol        = "tcp"
    security_groups = [aws_security_group.tfALBsg.id]
  }

  ingress {
    from_port       = 22
    to_port         = 22
    protocol        = "tcp"
    security_groups = [aws_security_group.tfALBsg.id] # 문제의 코드
  }

  egress {
.
.
.

해결 방안

resource "aws_security_group" "tfEC2sg" {
  name = "Terraform-EC2-HTTP,SSH-Access"
  ingress {
    from_port       = 80
    to_port         = 80
    protocol        = "tcp"
    security_groups = [aws_security_group.tfALBsg.id]
  }

  ingress {
    from_port       = 22
    to_port         = 22
    protocol        = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # 모든 대상으로 추가
    security_groups = [aws_security_group.tfALBsg.id]	
  }

  egress {
.
.
.

# 피드백

오태경박찬규
직접 코드로 인프라를 구성해보니 AWS 리소스별 옵션값들을 더 자세히 알 수 있었다.

#References

Leave a Comment