Cloud Mini Project (22.04.27~22.05.02)

박민선·2022년 5월 2일
0

1. IaC를 이용해 AWS 클라우드에 Wordpress 자동화 배포

설계도

1) Wordpress가 배포되어 있는 EC2 이미지 생성

Public IP : 3.36.77.188

RDS앤드포인트로 Mysql 접속
mysql -h wp-alb-61315699.ap-northeast-2.elb.amazonaws.com -u admin -p
DB설정
CREATE USER 'wordpress' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON wordpress.* TO wordpress;
FLUSH PRIVILEGES;
Exit

2) Terraform을 이용한 VPC 생성

#main.tf
resource "aws_vpc" "wp" {
  cidr_block = var.vpc_cidr
}

resource "aws_subnet" "wp_public_a" {
  vpc_id            = aws_vpc.wp.id
  cidr_block        = var.subnet_cidr_a
  availability_zone = var.az_a_name
  tags = {
    Name = "wp_public"
  }
  depends_on = [
    aws_vpc.wp
  ]
}

3) Subnet 생성 (Public 2개, Private 2개)

#main.tf
resource "aws_subnet" "wp_public_a" {
  vpc_id            = aws_vpc.wp.id
  cidr_block        = var.subnet_cidr_a
  availability_zone = var.az_a_name
  tags = {
    Name = "wp_public"
  }
  depends_on = [
    aws_vpc.wp
  ]
}

resource "aws_subnet" "wp_public_c" {
  vpc_id            = aws_vpc.wp.id
  cidr_block        = var.subnet_cidr_c
  availability_zone = var.az_c_name
  tags = {
    Name = "wp_public"
  }
  depends_on = [
    aws_vpc.wp
  ]
}

resource "aws_subnet" "wp_private_a" {
  vpc_id            = aws_vpc.wp.id
  cidr_block        = var.subnet_cidr_b
  availability_zone = var.az_a_name
  tags = {
    Name = "wp_private"
  }
  depends_on = [
    aws_vpc.wp
  ]
}

resource "aws_subnet" "wp_private_c" {
  vpc_id            = aws_vpc.wp.id
  cidr_block        = var.subnet_cidr_d
  availability_zone = var.az_c_name
  tags = {
    Name = "wp_private"
  }
  depends_on = [
    aws_vpc.wp
  ]
}

4) Private Subnet Group 생성 (RDS 생성 시)

#main.tf
resource "aws_db_subnet_group" "wp_private_subnet" {
  name       = "wp_private_subnet"
  subnet_ids = [aws_subnet.wp_private_a.id, aws_subnet.wp_private_c.id]

  tags = {
    Name = "My DB subnet group"
  }
}

5) Internet Gateway & Routing table 생성

#main.tf
resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.wp.id

  tags = {
    Name = "wordpress"
  }
  depends_on = [
    aws_vpc.wp
  ]
}

resource "aws_route_table" "rt" {
  vpc_id = aws_vpc.wp.id

  route {
    cidr_block = var.route_cidr_b
    gateway_id = aws_internet_gateway.gw.id
  }

  tags = {
    Name = "wordpress"
  }
  depends_on = [
    aws_subnet.wp_public_a
  ]
}

resource "aws_route_table_association" "a" {
  subnet_id      = aws_subnet.wp_public_a.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "c" {
  subnet_id      = aws_subnet.wp_public_c.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "b" {
  subnet_id      = aws_subnet.wp_private_a.id
  route_table_id = aws_route_table.rt.id
}

resource "aws_route_table_association" "d" {
  subnet_id      = aws_subnet.wp_private_c.id
  route_table_id = aws_route_table.rt.id

6) Security Group 생성

#sg.tf
resource "aws_security_group" "rds" {
  name        = "rds seciroty group"
  description = "Allow ssh inbound traffic"
  vpc_id      = aws_vpc.wp.id

  ingress {
    description = "ssh from rds"
    from_port   = var.rds_ingress_port
    to_port     = var.rds_ingress_port
    protocol    = "tcp"
    cidr_blocks = [aws_vpc.wp.cidr_block]
  }

  egress {
    from_port        = var.egress_port
    to_port          = var.egress_port
    protocol         = "-1"
    cidr_blocks      = [var.sg_cidr]
    ipv6_cidr_blocks = [var.rds_egress_ipv6_cidr]
  }

  tags = {
    Name = "rds_security_group"
  }
}

resource "aws_security_group" "webserver" {
  name   = "Allow SSH & HTTP"
  vpc_id = aws_vpc.wp.id

  ingress {
    from_port   = var.http_ingress_port
    to_port     = var.http_ingress_port
    protocol    = "tcp"
    cidr_blocks = [var.sg_cidr]
  }

  ingress {
    from_port   = var.ssh_ingress_port
    to_port     = var.ssh_ingress_port
    protocol    = "tcp"
    cidr_blocks = [var.sg_cidr]
  }

  egress {
    from_port   = var.egress_port
    to_port     = var.egress_port
    protocol    = "-1"
    cidr_blocks = [var.sg_cidr]
  }

  tags = {
    Name = "webserver_security_group"
  }

}

7) Web Server용 Instance 생성

#main.tf
resource "aws_key_pair" "web_admin" {
  key_name   = "web _admin"
  public_key = file("~/.ssh/web_admin.pub")

}

resource "aws_instance" "web_server" {
  ami                         = var.ami_id
  instance_type               = var.instance_type
  subnet_id                   = aws_subnet.wp_public_a.id
  vpc_security_group_ids      = [var.vpc_sg_id]
  key_name                    = aws_key_pair.web_admin.key_name
  associate_public_ip_address = "true"

  tags = {
    Name = "webserver_public"
  }

}

8) Database RDS 생성

#main_rds.tf
resource "aws_db_instance" "wordpress" {
  identifier           = "wordpress"
  allocated_storage    = 20
  engine               = var.rds_engine
  engine_version       = var.rds_engine_version
  instance_class       = var.rds_instance_class
  username             = var.rds_username
  password             = var.rds_password
  storage_type         = var.rds_storage_type
  db_subnet_group_name = var.rds_db_subnet_group_name
  skip_final_snapshot  = true
  parameter_group_name = var.rds_parameter_group_name
  db_name              = var.rds_db_name
  vpc_security_group_ids = [var.rds_vpc_security_group_ids]
}

9) Load Balancer 생성

#alb.tf
resource "aws_alb" "wp-alb" {
  name                             = "wp-alb"
  internal                         = false
  load_balancer_type               = "application"
  security_groups                  = [aws_security_group.webserver.id]
  subnets                          = [aws_subnet.wp_public_a.id, aws_subnet.wp_public_c.id]
  enable_cross_zone_load_balancing = true
}


resource "aws_alb_target_group" "wp-alb-tg" {
  name     = "wp-alb-tg"
  port     = var.http_ingress_port
  protocol = "HTTP"
  vpc_id   = aws_vpc.wp.id
}

resource "aws_alb_target_group_attachment" "wp-alb-tg-at" {
  target_group_arn = aws_alb_target_group.wp-alb-tg.arn
  target_id        = aws_instance.web_server.id
  port             = var.http_ingress_port
}

resource "aws_alb_listener" "wp-alb-listener" {
  load_balancer_arn = aws_alb.wp-alb.arn
  port              = var.http_ingress_port
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.wp-alb-tg.arn
  }
}

10) ALB DNS이름으로 Wordpress 접속 확인

DNS : wp-alb-61315699.ap-northeast-2.elb.amazonaws.com

11) AutoScaling 생성

#auto.tf
resource "aws_launch_configuration" "wp-auto" {
  name          = "web_config"
  image_id      = var.ami_id
  instance_type = var.instance_type
  key_name      = aws_key_pair.web_admin.key_name
}

resource "aws_autoscaling_group" "wp-auto-group" {
  name                      = "autoscalegroup"
  max_size                  = 3
  min_size                  = 2
  vpc_zone_identifier       = [var.subnet_a_id, var.subnet_c_id]
  health_check_grace_period = 30
  health_check_type         = "EC2"
  force_delete              = true
  launch_configuration = aws_launch_configuration.wp-auto.name
}

resource "aws_autoscaling_attachment" "asg_attachment" {
  autoscaling_group_name = aws_autoscaling_group.wp-auto-group.id
  lb_target_group_arn    = aws_alb_target_group.wp-alb-tg.arn
}

12) 변수파일 확인

#variable.tf (vpc)

variable "vpc_cidr" {
  description = "vpc cidr_block"
  type        = string
  default     = "20.0.0.0/24"
}

variable "subnet_cidr_a" {
  description = "public subnet_a cidr_block"
  type        = string
  default     = "20.0.0.0/27"
}

variable "subnet_cidr_c" {
  description = "public subnet_c cidr_block"
  type        = string
  default     = "20.0.0.64/27"
}

variable "subnet_cidr_b" {
  description = "private subnet_b cidr_block"
  type        = string
  default     = "20.0.0.128/27"
}

variable "subnet_cidr_d" {
  description = "private subnet_d cidr_block"
  type        = string
  default     = "20.0.0.192/27"
}

variable "route_cidr_b" {
  description = "route table cidr_block"
  type        = string
  default     = "0.0.0.0/0"
}

variable "rds_ingress_port" {
  description = "rds ingress port number"
  type        = number
  default     = 3306
}

variable "egress_port" {
  description = "egress port number"
  type        = number
  default     = 0
}

variable "sg_cidr" {
  description = "secret cidr_block"
  type        = string
  default     = "0.0.0.0/0"
}

variable "rds_egress_ipv6_cidr" {
  description = "rds ipv6 cidr_block"
  type        = string
  default     = "::/0"
}

variable "http_ingress_port" {
  description = "http ingress port number"
  type        = number
  default     = 80
}

variable "ssh_ingress_port" {
  description = "ssh ingress port number"
  type        = number
  default     = 22
}

variable "ami_id" {
  description = "ami id"
  type        = string
  default     = "ami-08f32c2e7c429873a"
}

variable "instance_type" {
  description = "instance type"
  type        = string
  default     = "t2.micro"
}

variable "az_a_name" {
  description = "availability zone a name"
  type        = string
  default     = "ap-northeast-2a"
}

variable "az_c_name" {
  description = "availability zone c name"
  type        = string
  default     = "ap-northeast-2c"
}

variable "vpc_sg_id" {
  description = "vpc security group id"
  type        = string
  default     = "sg-0a30ce12f2ccc5571"
}

variable "subnet_a_id" {
  description = "public subnet a id"
  type        = string
  default     = "subnet-05d83bf41a0643251"
}

variable "subnet_c_id" {
  description = "public subnet c id"
  type        = string
  default     = "subnet-09ed00cc49f39e503"
}
#variable.tf (RDS)

variable "rds_engine" {
  description = "rds engine"
  type        = string
  default     = "mysql"
}

variable "rds_engine_version" {
  description = "rds engine version"
  type        = string
  default     = "8.0.28"
}

variable "rds_instance_class" {
  description = "rds instance class"
  type        = string
  default     = "db.t3.micro"
}

variable "rds_username" {
  description = "rds username"
  type        = string
  default     = "admin"
}

variable "rds_password" {
  description = "rds password"
  type        = string
  default     = "alstjs10"
}

variable "rds_storage_type" {
  description = "rds storage type"
  type        = string
  default     = "gp2"
}

variable "rds_db_subnet_group_name" {
  description = "rds db subnet group name"
  type        = string
  default     = "wp_private_subnet"
}

variable "rds_parameter_group_name" {
  description = "rds parameter gorup name"
  type        = string
  default     = "default.mysql8.0"
}

variable "rds_db_name" {
  description = "rds db name"
  type        = string
  default     = "wordpress"
}

variable "rds_vpc_security_group_ids" {
  description = "rds vpc security group ids"
  type        = string
  default     = "sg-0a4434746589f00ca"
}


profile
클라우드신생아

0개의 댓글