- AWS
0. 파일 구조
terraform
aws-set ec2-alb
1. VPC
# mkdir aws-set && cd $_
# vi variables.tf
variable "security_group_name" {
description = "The name of the security group"
type = string
default = "terraform-example-instance"
}
# vi main.tf
provider "aws" {
region = "ap-northeast-2"
}
* VPC
resource "aws_vpc" "test_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "test-vpc"
}
}
data "aws_availability_zones" "available" {
state = "available" # 리전의 가용영역 중 사용 가능한 영역의 정보를 가져온다
}
resource "aws_subnet" "test-pub_2a" { # resource type # resource name
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.0.0/20"
map_public_ip_on_launch = true # 퍼블릭 IP 할당 여부
availability_zone = data.aws_availability_zones.available.names[0] # 가용 영역의 이름을 가져온다(ap-northeast-2a)
tags = {
Name = "test-pub-2a"
}
}
resource "aws_subnet" "test-pub_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.16.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pub-2b"
}
}
resource "aws_subnet" "test-pub_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.32.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pub-2c"
}
}
resource "aws_subnet" "test-pub_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.48.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pub-2d"
}
}
resource "aws_internet_gateway" "test_igw" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-igw"
}
}
resource "aws_subnet" "test-pvt_2a" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.64.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "test-pvt-2a"
}
}
resource "aws_subnet" "test-pvt_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.80.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pvt-2b"
}
}
resource "aws_subnet" "test-pvt_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.96.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pvt-2c"
}
}
resource "aws_subnet" "test-pvt_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.112.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pvt-2d"
}
}
resource "aws_route_table" "test_pub_rtb" {
vpc_id = aws_vpc.test_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.test_igw.id
}
tags = {
Name = "test-pub-rtb"
}
}
resource "aws_route_table" "test_pvt_rtb" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-pvt-rtb"
}
}
resource "aws_route_table_association" "test-pub_2a_association" {
subnet_id = aws_subnet.test-pub_2a.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2b_association" {
subnet_id = aws_subnet.test-pub_2b.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2c_association" {
subnet_id = aws_subnet.test-pub_2c.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2d_association" {
subnet_id = aws_subnet.test-pub_2d.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pvt_2a_association" {
subnet_id = aws_subnet.test-pvt_2a.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2b_association" {
subnet_id = aws_subnet.test-pvt_2b.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2c_association" {
subnet_id = aws_subnet.test-pvt_2c.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2d_association" {
subnet_id = aws_subnet.test-pvt_2d.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
* EC2
resource "aws_instance" "example" {
ami = "ami-035da6a0773842f64"
instance_type = "t2.micro"
subnet_id = aws_subnet.test-pub_2a.id
vpc_security_group_ids = [aws_security_group.instance.id]
key_name = "test-key"
user_data = file("user-data.sh")
tags = {
Name = "terraform-example"
}
}
resource "aws_security_group" "instance" {
vpc_id = aws_vpc.test_vpc.id
name = var.security_group_name
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["106.253.56.124/32"]
}
ingress {
# from to range의 의미 from ~ to 까지의 포트로 사용자가 접근하면 허용한다.
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terraform-sg"
}
}
* vi outputs.tf
output "public_ip" {
value = aws_instance.example.public_ip
description = "The public IP of the Instance"
}
output "public_dns" {
value = aws_instance.example.public_dns
description = "The Public dns of the Instance"
}
output "private_ip" {
value = aws_instance.example.private_ip
description = "The Private_ip of the Instance"
}
# terraform init
# terraform plan
# terraform apply (-auto-approve 옵션을 추가하면 yes 생략 가능)
# terraform output public_ip
# terraform destroy (-auto-approve 옵션을 추가하면 yes 생략 가능)
* acl 설정
- 처음 사용자 데이터에서 이상이 있어서 S3버킷의 ACL 부분을 활성화함
- food.tar 파일을 퍼블릭으로 설정
- terraform destroy 후 terraform apply.
2. ec2 alb
# mkdir ec2-alb && cd $_
# vi main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "test_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true # ec2에 dns 주소 부여
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "test-vpc"
}
}
data "aws_availability_zones" "available" {
state = "available" # 리전의 가용영역 중 사용 가능한 영역의 정보를 가져온다
}
resource "aws_subnet" "test-pub_2a" { # resource type # resource name
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.0.0/20"
map_public_ip_on_launch = true # 퍼블릭 IP 할당 여부
availability_zone = data.aws_availability_zones.available.names[0] # 가용 영역의 이름을 가져온다(ap-northeast-2a)
tags = {
Name = "test-pub-2a"
}
}
resource "aws_subnet" "test-pub_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.16.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pub-2b"
}
}
resource "aws_subnet" "test-pub_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.32.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pub-2c"
}
}
resource "aws_subnet" "test-pub_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.48.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pub-2d"
}
}
resource "aws_internet_gateway" "test_igw" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-igw"
}
}
resource "aws_subnet" "test-pvt_2a" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.64.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "test-pvt-2a"
}
}
resource "aws_subnet" "test-pvt_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.80.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pvt-2b"
}
}
resource "aws_subnet" "test-pvt_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.96.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pvt-2c"
}
}
resource "aws_subnet" "test-pvt_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.112.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pvt-2d"
}
}
resource "aws_route_table" "test_pub_rtb" {
vpc_id = aws_vpc.test_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.test_igw.id
}
tags = {
Name = "test-pub-rtb"
}
}
resource "aws_route_table" "test_pvt_rtb" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-pvt-rtb"
}
}
resource "aws_route_table_association" "test-pub_2a_association" {
subnet_id = aws_subnet.test-pub_2a.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2b_association" {
subnet_id = aws_subnet.test-pub_2b.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2c_association" {
subnet_id = aws_subnet.test-pub_2c.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2d_association" {
subnet_id = aws_subnet.test-pub_2d.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pvt_2a_association" {
subnet_id = aws_subnet.test-pvt_2a.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2b_association" {
subnet_id = aws_subnet.test-pvt_2b.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2c_association" {
subnet_id = aws_subnet.test-pvt_2c.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2d_association" {
subnet_id = aws_subnet.test-pvt_2d.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
variable "security_group_name" {
description = "The name of the security group"
type = string
default = "test-sg-alb"
}
resource "aws_security_group" "test_web_sg_alb" {
name = var.security_group_name
# vpc_id = data.aws_vpc.test_vpc.id
vpc_id = aws_vpc.test_vpc.id
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"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test-sg-alb"
}
}
resource "aws_lb" "frontend" {
name = "alb-example"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.test_web_sg_alb.id]
subnets = [
aws_subnet.test-pub_2a.id,
aws_subnet.test-pub_2c.id
]
tags = {
Name = "test-alb"
}
lifecycle { create_before_destroy = true }
}
resource "aws_instance" "alb_vm_01" {
ami = "ami-035da6a0773842f64"
instance_type = "t2.micro"
subnet_id = aws_subnet.test-pub_2a.id
vpc_security_group_ids = [aws_security_group.test_web_sg_alb.id]
key_name = "test-key"
user_data = <<-EOF
#! /bin/bash
yum install -y httpd
systemctl enable --now httpd
echo "Hello, Terraform01" > /var/www/html/index.html
EOF
tags = {
Name = "ALB01"
}
}
resource "aws_instance" "alb_vm_02" {
ami = "ami-035da6a0773842f64"
instance_type = "t2.micro"
subnet_id = aws_subnet.test-pub_2c.id
vpc_security_group_ids = [aws_security_group.test_web_sg_alb.id]
key_name = "test-key"
user_data = <<-EOF
#! /bin/bash
yum install -y httpd
systemctl enable --now httpd
echo "Hello, Terraform02" > /var/www/html/index.html
EOF
tags = {
Name = "ALB02"
}
}
resource "aws_lb_target_group" "tg" {
name = "TargetGroup"
port = 80
target_type = "instance"
protocol = "HTTP"
vpc_id = aws_vpc.test_vpc.id
health_check {
path = "/"
protocol = "HTTP"
matcher = "200"
interval = 15
timeout = 3
healthy_threshold = 2
unhealthy_threshold = 2
}
}
resource "aws_alb_target_group_attachment" "tgattachment01" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.alb_vm_01.id
port = 80
}
resource "aws_alb_target_group_attachment" "tgattachment02" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.alb_vm_02.id
port = 80
}
resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.frontend.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg.arn
}
}
output "lb_dns_name" {
description = "The DNS name of the load balancer."
value = aws_lb.frontend.dns_name
}
# terraform init
# terraform validate (구성만 참조하고 원격 상태, 공급자 API 등과 같은 원격 서비스에 액세스하지 않고 디렉터리의 구성 파일을 유효성 검사합니다.)
# terraform plan
# terraform apply -auto-approve
# terraform output lb_dns_name
# terraform destroy -auto-approve
3. asg
# vi variables.tf
variable "instance_security_group_name" {
description = "The name of the security group for the EC2 Instances"
type = string
default = "terraform-example-instance"
}
variable "http_port" {
description = "The port the server will use for HTTP requests"
type = number
default = 80
}
variable "ssh_port" {
description = "The port the server will use for SSH requests"
type = number
default = 22
}
variable "alb_name" {
description = "The name of the ALB"
type = string
default = "terraform-asg-example"
}
variable "alb_security_group_name" {
description = "The name of the security group for the ALB"
type = string
default = "terraform-example-alb"
}
# vi main.tf
provider "aws" {
region = "ap-northeast-2"
}
### test-vpc ###
resource "aws_vpc" "test_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true # ec2에 dns 주소 부여
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "test-vpc"
}
}
data "aws_availability_zones" "available" {
state = "available" # 리전의 가용영역 중 사용 가능한 영역의 정보를 가져온다
}
resource "aws_subnet" "test-pub_2a" { # resource type # resource name
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.0.0/20"
map_public_ip_on_launch = true # 퍼블릭 IP 할당 여부
availability_zone = data.aws_availability_zones.available.names[0] # 가용 영역의 이름을 가져온다(ap-northeast-2a)
tags = {
Name = "test-pub-2a"
}
}
resource "aws_subnet" "test-pub_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.16.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pub-2b"
}
}
resource "aws_subnet" "test-pub_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.32.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pub-2c"
}
}
resource "aws_subnet" "test-pub_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.48.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pub-2d"
}
}
resource "aws_internet_gateway" "test_igw" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-igw"
}
}
resource "aws_subnet" "test-pvt_2a" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.64.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "test-pvt-2a"
}
}
resource "aws_subnet" "test-pvt_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.80.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pvt-2b"
}
}
resource "aws_subnet" "test-pvt_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.96.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pvt-2c"
}
}
resource "aws_subnet" "test-pvt_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.112.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pvt-2d"
}
}
resource "aws_route_table" "test_pub_rtb" {
vpc_id = aws_vpc.test_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.test_igw.id
}
tags = {
Name = "test-pub-rtb"
}
}
resource "aws_route_table" "test_pvt_rtb" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-pvt-rtb"
}
}
resource "aws_route_table_association" "test-pub_2a_association" {
subnet_id = aws_subnet.test-pub_2a.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2b_association" {
subnet_id = aws_subnet.test-pub_2b.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2c_association" {
subnet_id = aws_subnet.test-pub_2c.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2d_association" {
subnet_id = aws_subnet.test-pub_2d.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pvt_2a_association" {
subnet_id = aws_subnet.test-pvt_2a.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2b_association" {
subnet_id = aws_subnet.test-pvt_2b.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2c_association" {
subnet_id = aws_subnet.test-pvt_2c.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2d_association" {
subnet_id = aws_subnet.test-pvt_2d.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
### asg ###
resource "aws_security_group" "instance" {
name = var.instance_security_group_name
vpc_id = aws_vpc.test_vpc.id
ingress {
from_port = var.http_port
to_port = var.http_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_launch_configuration" "example" {
image_id = "ami-035da6a0773842f64"
instance_type = "t2.micro"
security_groups = [aws_security_group.instance.id]
key_name = "test-key"
user_data = file("user-data.sh")
# Required when using a launch configuration with an auto scaling group.
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "example" {
launch_configuration = aws_launch_configuration.example.name
vpc_zone_identifier = [
aws_subnet.test-pub_2a.id,
aws_subnet.test-pub_2c.id
]
target_group_arns = [aws_lb_target_group.asg.arn]
health_check_type = "ELB"
min_size = 2
desired_capacity = 2
max_size = 4
tag {
key = "Name"
value = "terraform-asg-example"
propagate_at_launch = true
}
}
resource "aws_lb" "example" {
name = var.alb_name
load_balancer_type = "application"
subnets = [
aws_subnet.test-pub_2a.id,
aws_subnet.test-pub_2b.id,
aws_subnet.test-pub_2c.id,
aws_subnet.test-pub_2d.id
]
security_groups = [aws_security_group.alb.id]
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.example.arn
port = var.http_port
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.asg.arn
}
}
resource "aws_lb_target_group" "asg" {
name = var.alb_name
port = var.http_port
protocol = "HTTP"
vpc_id = aws_vpc.test_vpc.id
health_check {
path = "/"
protocol = "HTTP"
matcher = "200"
interval = 15
timeout = 3
healthy_threshold = 2
unhealthy_threshold = 2
}
}
resource "aws_security_group" "alb" {
vpc_id = aws_vpc.test_vpc.id
name = var.alb_security_group_name
# Allow inbound HTTP requests
ingress {
from_port = var.http_port
to_port = var.http_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow all outbound requests
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_autoscaling_policy" "scale_in" {
name = "ScaleInPolicy"
autoscaling_group_name = aws_autoscaling_group.example.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = -1
cooldown = 300
}
resource "aws_cloudwatch_metric_alarm" "scale_in" {
alarm_description = "Monitors CPU utilization for Terramino ASG"
alarm_actions = [aws_autoscaling_policy.scale_in.arn]
alarm_name = "ScaleInAlarm"
comparison_operator = "LessThanOrEqualToThreshold"
namespace = "AWS/EC2"
metric_name = "CPUUtilization"
threshold = "30"
evaluation_periods = "1"
period = "300"
statistic = "Average"
dimensions = {
AutoScalingGroupName = aws_autoscaling_group.example.name
}
}
resource "aws_autoscaling_policy" "scale_out" {
name = "ScaleOutPolicy"
autoscaling_group_name = aws_autoscaling_group.example.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = 1
cooldown = 300
}
resource "aws_cloudwatch_metric_alarm" "scale_out" {
alarm_description = "Monitors CPU utilization for Terramino ASG"
alarm_actions = [aws_autoscaling_policy.scale_out.arn]
alarm_name = "ScaleOutAlarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
namespace = "AWS/EC2"
metric_name = "CPUUtilization"
threshold = "70"
evaluation_periods = "1"
period = "300"
statistic = "Average"
dimensions = {
AutoScalingGroupName = aws_autoscaling_group.example.name
}
}
# vi outputs.tf
output "alb_dns_name" {
value = aws_lb.example.dns_name
description = "The domain name of the load balancer"
}
4. RDS
# cd ec2-asg
# vi main.tf
provider "aws" {
region = "ap-northeast-2"
}
### test-vpc ###
resource "aws_vpc" "test_vpc" {
cidr_block = "192.168.0.0/16"
enable_dns_hostnames = true # ec2에 dns 주소 부여
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "test-vpc"
}
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_subnet" "test-pub_2a" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.0.0/20"
map_public_ip_on_launch = true # 퍼블릭 IP 할당 여부
availability_zone = data.aws_availability_zones.available.names[0] # 가용 영역의 이름을 가져온다(ap-northeast-2a)
tags = {
Name = "test-pub-2a"
}
}
resource "aws_subnet" "test-pub_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.16.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pub-2b"
}
}
resource "aws_subnet" "test-pub_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.32.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pub-2c"
}
}
resource "aws_subnet" "test-pub_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.48.0/20"
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pub-2d"
}
}
resource "aws_eip" "ngw"{
}
resource "aws_nat_gateway" "test_ngw"{
allocation_id = aws_eip.ngw.id
subnet_id = aws_subnet.test-pub_2d.id
tags = {
Name = "test-ngw"
}
}
resource "aws_route_table" "test_pvt_rtb" {
vpc_id = aws_vpc.test_vpc.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.test_ngw.id
}
tags = {
Name = "test-pvt-rtb"
}
}
resource "aws_internet_gateway" "test_igw" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "test-igw"
}
}
resource "aws_subnet" "test-pvt_2a" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.64.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "test-pvt-2a"
}
}
resource "aws_subnet" "test-pvt_2b" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.80.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "test-pvt-2b"
}
}
resource "aws_subnet" "test-pvt_2c" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.96.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[2]
tags = {
Name = "test-pvt-2c"
}
}
resource "aws_subnet" "test-pvt_2d" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "192.168.112.0/20"
map_public_ip_on_launch = false
availability_zone = data.aws_availability_zones.available.names[3]
tags = {
Name = "test-pvt-2d"
}
}
resource "aws_route_table" "test_pub_rtb" {
vpc_id = aws_vpc.test_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.test_igw.id
}
tags = {
Name = "test-pub-rtb"
}
}
resource "aws_route_table_association" "test-pub_2a_association" {
subnet_id = aws_subnet.test-pub_2a.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2b_association" {
subnet_id = aws_subnet.test-pub_2b.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2c_association" {
subnet_id = aws_subnet.test-pub_2c.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pub_2d_association" {
subnet_id = aws_subnet.test-pub_2d.id
route_table_id = aws_route_table.test_pub_rtb.id
}
resource "aws_route_table_association" "test-pvt_2a_association" {
subnet_id = aws_subnet.test-pvt_2a.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2b_association" {
subnet_id = aws_subnet.test-pvt_2b.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2c_association" {
subnet_id = aws_subnet.test-pvt_2c.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
resource "aws_route_table_association" "test-pvt_2d_association" {
subnet_id = aws_subnet.test-pvt_2d.id
route_table_id = aws_route_table.test_pvt_rtb.id
}
### asg ###
resource "aws_security_group" "instance" {
name = var.instance_security_group_name
vpc_id = aws_vpc.test_vpc.id
ingress {
from_port = var.http_port
to_port = var.http_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_launch_configuration" "example" {
image_id = "ami-035da6a0773842f64"
instance_type = "t2.micro"
security_groups = [aws_security_group.instance.id]
key_name = "test-key"
user_data = file("user-data.sh")
# Required when using a launch configuration with an auto scaling group.
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "example" {
launch_configuration = aws_launch_configuration.example.name
vpc_zone_identifier = [
aws_subnet.test-pub_2a.id,
aws_subnet.test-pub_2c.id
]
target_group_arns = [aws_lb_target_group.asg.arn]
health_check_type = "ELB"
min_size = 1
desired_capacity = 1
max_size = 4
tag {
key = "Name"
value = "terraform-asg-example"
propagate_at_launch = true
}
}
resource "aws_lb" "example" {
name = var.alb_name
load_balancer_type = "application"
subnets = [
aws_subnet.test-pub_2a.id,
aws_subnet.test-pub_2b.id,
aws_subnet.test-pub_2c.id,
aws_subnet.test-pub_2d.id
]
security_groups = [aws_security_group.alb.id]
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.example.arn
port = var.http_port
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.asg.arn
}
}
resource "aws_lb_target_group" "asg" {
name = var.alb_name
port = var.http_port
protocol = "HTTP"
vpc_id = aws_vpc.test_vpc.id
health_check {
path = "/health/"
protocol = "HTTP"
matcher = "200"
interval = 15
timeout = 3
healthy_threshold = 2
unhealthy_threshold = 2
}
}
resource "aws_security_group" "alb" {
vpc_id = aws_vpc.test_vpc.id
name = var.alb_security_group_name
# Allow inbound HTTP requests
ingress {
from_port = var.http_port
to_port = var.http_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow all outbound requests
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_autoscaling_policy" "scale_in" {
name = "ScaleInPolicy"
autoscaling_group_name = aws_autoscaling_group.example.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = -1
cooldown = 300
}
resource "aws_cloudwatch_metric_alarm" "scale_in" {
alarm_description = "Monitors CPU utilization for Terramino ASG"
alarm_actions = [aws_autoscaling_policy.scale_in.arn]
alarm_name = "ScaleInAlarm"
comparison_operator = "LessThanOrEqualToThreshold"
namespace = "AWS/EC2"
metric_name = "CPUUtilization"
threshold = "30"
evaluation_periods = "1"
period = "300"
statistic = "Average"
dimensions = {
AutoScalingGroupName = aws_autoscaling_group.example.name
}
}
resource "aws_autoscaling_policy" "scale_out" {
name = "ScaleOutPolicy"
autoscaling_group_name = aws_autoscaling_group.example.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = 1
cooldown = 300
}
resource "aws_cloudwatch_metric_alarm" "scale_out" {
alarm_description = "Monitors CPU utilization for Terramino ASG"
alarm_actions = [aws_autoscaling_policy.scale_out.arn]
alarm_name = "ScaleOutAlarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
namespace = "AWS/EC2"
metric_name = "CPUUtilization"
threshold = "70"
evaluation_periods = "1"
period = "300"
statistic = "Average"
dimensions = {
AutoScalingGroupName = aws_autoscaling_group.example.name
}
}
### RDS
resource "aws_db_subnet_group" "test_rds_subnet" {
name = "main"
subnet_ids = [aws_subnet.test-pvt_2a.id, aws_subnet.test-pvt_2d.id]
tags = {
Name = "test-rds-subnet"
}
}
resource "aws_security_group" "test_sg_rds" {
name = var.rds_name
vpc_id = aws_vpc.test_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"]
}
}
resource "aws_db_instance" "test_rds" {
allocated_storage = 20
db_name = "wordpress"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
username = "yunhyeong"
password = "nwmc1023!!"
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
db_subnet_group_name = aws_db_subnet_group.test_rds_subnet.name
vpc_security_group_ids = [aws_security_group.test_sg_rds.id]
}
# vi outputs.tf
output "alb_dns_name" {
value = aws_lb.example.dns_name
description = "The domain name of the load balancer"
}
output "rds_endpoint" {
value = aws_db_instance.test_rds.endpoint
description = "The endpoint of the rds"
}
# vi outputs.tf
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "public_ip_address" {
value = azurerm_linux_virtual_machine.myterraformvm.public_ip_address
}
output "tls_private_key" {
value = tls_private_key.example_ssh.private_key_pem
sensitive = true
}
- 왼쪽 탭에서 test-key.pem내려 받기
- test-key 파일 AWS cloudshell로 업로드
- cloudshell에서 내려받은 키를 올린다.
- test-key 권한 변경
- private 내에 있는 인스턴스에 접근(ami 이미지를 그대로 넣었기 때문에 public IP가 생김)
- RDS에 접근(RDS endpoint 활용)
- database 확인
5. bastion_host
resource "aws_instance" "test_bastion" {
ami = "ami-035da6a0773842f64"
instance_type = "t2.micro"
subnet_id = aws_subnet.test-pub_2a.id
vpc_security_group_ids = [aws_security_group.instance.id]
key_name = "test-key"
user_data = file("bastion-data.sh")
tags = {
Name = "bastion-host"
}
}
- asg경로안에 있는 main.tf 파일에 위의 내용 추가
- scp -i test-key.pem test-key.pem ec2-user@3.38.116.29:/ec2-user/home -> bastion host에 키 전달
- cloudshell에서 bastion_host로 접근한다.
- bastion_host에서 다른 인스턴스로 접근
- sudo yes > /dev/null & ; ScaleOut 확인을 위한 부하 테스트(sudo yes > /dev/null &)
- sudo pkill -9 yes; 어느 정도 부하가 생기면 멈춘다; Scale IN알람이 발생
'Cloud Solution Architect > AWS' 카테고리의 다른 글
AWS-CloudFormation (0) | 2023.05.16 |
---|---|
AWS-CLI (0) | 2023.05.15 |
2차 세미 프로젝트 - Openstack (0) | 2023.05.11 |
AWS - Amazon Inspector, CloudWatchLog, NAT Instance (0) | 2023.05.02 |
AWS - CloudFront, Cloud 보안, ACM을 활용한 HTTPS 프로토콜 접속 (0) | 2023.05.01 |