Terraform

Terraform AWS 구성 (ecs 기반)

KK_Ryong 2023. 4. 11. 10:40

main.tf (provider.tf)

#aws configure------------------------------
provider "aws" {
  access_key = "" #<  IAM 으로 생성한 계정
  secret_key = ""  #<  IAM 으로 생성한 계정의 Secret Key
  region     = "ap-northeast-2" #생성할 리전
}

variable.tf (따로 입력 뜸) 

variable "availability_zone" {
  description = "Seoul region availability zone"
  type = list
  default = ["ap-northeast-2a", "ap-northeast-2c"]
}
variable "domain" {
  type = string
}

network.tf

#VPC 생성------------------------------
resource "aws_vpc" "stg-toon-vpc" {                 #resource "소스" "개별이름"
  cidr_block           = "30.0.0.0/16"
  instance_tenancy     = "default"
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = {
    Name = "stg-toon-vpc"
  }
}
#internet_gateway생성------------------------------
resource "aws_internet_gateway" "toon-stg-igw" {
  vpc_id = "${aws_vpc.stg-toon-vpc.id}"
  tags = {
    Name = "toon-stg-igw"
  }
}

data "aws_availability_zones" "available" {
  exclude_names = ["ap-northeast-2d", "ap-northeast-2b"]
}
#Subnet 생성------------------------------
resource "aws_subnet" "toon-stg-subnet-public-ap-northeast-2a" {
  vpc_id                  = aws_vpc.stg-toon-vpc.id
  count                   = length(data.aws_availability_zones.available.names)
  cidr_block              = "30.0.${0 + count.index}.0/24"
  map_public_ip_on_launch = true
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  tags = {
    Name = "toon-stg-subnet-public-ap-northeast-2"
  }
}

resource "aws_subnet" "toon-stg-subnet-private-ap-northeast-2a" {
  vpc_id                  = aws_vpc.stg-toon-vpc.id
  count                   = length(data.aws_availability_zones.available.names)
  cidr_block              = "30.0.${10 + count.index}.0/24"
  map_public_ip_on_launch = false
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  tags = {
    Name = "toon-stg-subnet-private-ap-northeast-2"
  }
}

#Routing Table생성------------------------------
resource "aws_route_table" "stg-toon-rtb-public" {
  vpc_id = aws_vpc.stg-toon-vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.toon-stg-igw.id
  }
  tags = {
    Name = "stg-toon-rtb-public"
  }
}
resource "aws_route_table" "stg-toon-rtb-private" {
  vpc_id = aws_vpc.stg-toon-vpc.id
  tags = {
    Name = "stg-toon-rtb-private"
  }
}

#라우터 테이블에 서브넷 연결------------------------------
resource "aws_route_table_association" "stg-toon-rtb-public" {
  count          = length(aws_subnet.toon-stg-subnet-public-ap-northeast-2a)
  route_table_id = aws_route_table.stg-toon-rtb-public.id
  subnet_id      = aws_subnet.toon-stg-subnet-public-ap-northeast-2a[count.index].id
}
resource "aws_route_table_association" "stg-toon-rtb-private" {
  count          = length(aws_subnet.toon-stg-subnet-private-ap-northeast-2a)
  route_table_id = aws_route_table.stg-toon-rtb-private.id
  subnet_id      = aws_subnet.toon-stg-subnet-private-ap-northeast-2a[count.index].id
}

ALB.tf

#ALB생성------------------------------
resource "aws_lb" "toon-stg-alb" {
  name               = "toon-stg-alb"
  subnets            = aws_subnet.toon-stg-subnet-public-ap-northeast-2a[*].id
  load_balancer_type = "application"
  security_groups    = [aws_security_group.toon-stg-alb-sg.id]
  tags = {    
    Name = "toon-stg-alb"
  }
}

resource "aws_lb_listener" "http_forward" {
  load_balancer_arn = aws_lb.toon-stg-alb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
  depends_on = [aws_lb.toon-stg-alb]
}
#대상그룹 생성------------------------------
resource "aws_lb_target_group" "toon-stg-alb-tg" {
  name        = "toon-stg-alb-tg"
  port        = 80
  protocol    = "HTTP"
  vpc_id      = aws_vpc.stg-toon-vpc.id
  target_type = "instance"
  health_check {
    enabled             = true
    interval            = 300
    path                = "/"
    timeout             = 60
    matcher             = "200"
    healthy_threshold   = 5
    unhealthy_threshold = 5
  }

  lifecycle {
    create_before_destroy = true
  }
 
}

sg.tf

#보안 그룹 생성------------------------------
resource "aws_security_group" "toon-stg-alb-sg" {
  vpc_id = aws_vpc.stg-toon-vpc.id
  name   = "toon-stg-alb-sg"
  tags = {
    Name = "toon-stg-alb-sg"
  }
  ingress {
    protocol    = "tcp"
    from_port   = 80
    to_port     = 80
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    protocol    = "tcp"
    from_port   = 443
    to_port     = 443
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    protocol    = "-1"
    from_port   = 0
    to_port     = 0
    cidr_blocks = ["0.0.0.0/0"]
  }
}
#보안 규칙 생성------------------------------
resource "aws_security_group" "toon-stg-ecs_tasks" {
  vpc_id = aws_vpc.stg-toon-vpc.id
  name   = "toon-stg-ecs_tasks"
  tags = {
    Name = "toon-stg-ecs_tasks"
  }
  ingress {
    protocol        = "tcp"
    from_port       = 80
    to_port         = 80
    cidr_blocks     = ["0.0.0.0/0"]
    security_groups = [aws_security_group.toon-stg-alb-sg.id]
  }

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

route53

resource "aws_route53_zone" "BBB.co.kr" {
    name = "BBB.co.kr" #호스팅 영역 이름
    comment = "BBB.co.kr"
}

#IP 기반 A레코드
resource "aws_route53_record" "AAA.BBB.co.kr-A" {
    zone_id = aws_route53_zone.toon.zone_id #route53 호스팅 영역 ID
    name    = "AAA.BBB.co.kr" #레코드 이름
    type    = "A"
    records = ["8.8.8.8"] #전달할 IP 
    ttl     = "300"

}
#ALB 기반 A레코드
resource "aws_route53_record" "AAA.BBB.co.kr-A" {
    zone_id = aws_route53_zone.toon.zone_id #호스팅 영역 ID
    name    = "AAA.BBB.co.kr-A" #레코드 이름
    type    = "A"

    alias {
        name    = aws_lb.toon-stg-alb.dns_name  #연결할 ALB
        zone_id = aws_lb.toon-stg-alb.zone_id  #ALB hosted zone id
        evaluate_target_health = true
    }
}

ecr.tf (미완성)

resource "aws_ecr_repository" "foo" {
  name                 = "toon-stg-ecr"
  image_tag_mutability = "MUTABLE"
  image_scanning_configuration {
    scan_on_push = true
  }
}

resource "null_resource" "null_for_ecr_get_login_password" {
  provisioner "local-exec" {
    command = <<EOF
      aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin [account].dkr.ecr.ap-northeast-2.amazonaws.com
    EOF
  }
}
output "ecr_registry_id" {
  value = aws_ecr_repository.foo.registry_id
}
output "ecr_repository_url" {
  value = aws_ecr_repository.foo.repository_url
}

ecf.tf(미완성)(가져오긴 했으나 적용x)

data "aws_iam_policy_document" "ecs_task_execution_role" {
  version = "2012-10-17"
  statement {
    sid     = ""
    effect  = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}
resource "aws_iam_role" "ecs_task_execution_role" {
  name               = "ecs-staging-execution-role"
  assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_role.json
}
resource "aws_iam_role_policy_attachment" "ecs_task_execution_role" {
  role       = aws_iam_role.ecs_task_execution_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
data "template_file" "service" {
  template = file(var.tpl_path)
  vars = {
    region             = "ap-northeast-2"
    aws_ecr_repository = aws_ecr_repository.repo.repository_url
    tag                = "latest"
    container_port     = 80
    host_port          = 80
    app_name           = var.app_name
  }
}

'Terraform' 카테고리의 다른 글

terraform code (alb)  (0) 2023.08.31
terraform code (ec2)  (0) 2023.08.31
terraform code (network)  (0) 2023.08.31
[Terraform] Auto Scaling  (0) 2022.03.16
[Terraform] 설치 및 인프라 생성 (AWS IaC 용)  (0) 2022.03.02