Ssoon

[T101-3주차] 03 테라폼 상태 관리하기 - (5) terraform_remote_state 데이터 소스 본문

Terraform 101 Study

[T101-3주차] 03 테라폼 상태 관리하기 - (5) terraform_remote_state 데이터 소스

구구달스 2022. 11. 5. 13:19
CloudNet@ 팀의 가시다님이 진행하는 Terraform 101 Study 03주차 정리입니다.

📌 terraform_remote_state 데이터 소스를 사용하면 다른 테라폼 구성 세트에 저장된 테라폼 상태 파일을 가져올 수 있습니다.

 

GitHub - kschoi728/T101: Terraform 101 Study

Terraform 101 Study. Contribute to kschoi728/T101 development by creating an account on GitHub.

github.com

웹서버 클러스터를 생성합니다 / stage/services/webserver-cluster/main.tf

data.terraform_remote_state.<NAME>.ouputs.<ATTRIBUTE>

모든 출력 변수(output variables)는 상태 파일(state file)에 저장되며 속성 참조(attribute reference)를 사용하여 terraform_remote_state 데이터 소스에서 읽을 수 있습니다.

 

terraform {
  backend "s3" {
    bucket = "ssoon-t101study-tfstate-week3-files"
    key    = "stage/services/webserver-cluster/terraform.tfstate"
    region = "ap-northeast-2"
    dynamodb_table = "terraform-locks-week3-files"
  }
}

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

data "terraform_remote_state" "db" {
  backend = "s3"
  config = {
    bucket = "ssoon-t101study-tfstate-week3-files"
    key    = "stage/data-stores/ssoon_sql/terraform.tfstate"
    region = "ap-northeast-2"
  }
}

resource "aws_subnet" "ssoon_subnet1" {
  vpc_id     = data.terraform_remote_state.db.outputs.vpcid
  cidr_block = "10.10.1.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "t101-subnet1"
  }
}

resource "aws_subnet" "ssoon_subnet2" {
  vpc_id     = data.terraform_remote_state.db.outputs.vpcid
  cidr_block = "10.10.2.0/24"

  availability_zone = "ap-northeast-2c"

  tags = {
    Name = "t101-subnet2"
  }
}

resource "aws_internet_gateway" "ssoon_igw" {
  vpc_id = data.terraform_remote_state.db.outputs.vpcid

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

resource "aws_route_table" "ssoon_rt" {
  vpc_id = data.terraform_remote_state.db.outputs.vpcid

  tags = {
    Name = "t101-rt"
  }
}

resource "aws_route_table_association" "ssoon_rtassociation1" {
  subnet_id      = aws_subnet.ssoon_subnet1.id
  route_table_id = aws_route_table.ssoon_rt.id
}

resource "aws_route_table_association" "ssoon_rtassociation2" {
  subnet_id      = aws_subnet.ssoon_subnet2.id
  route_table_id = aws_route_table.ssoon_rt.id
}

resource "aws_route" "ssoon_defaultroute" {
  route_table_id         = aws_route_table.ssoon_rt.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.ssoon_igw.id
}

resource "aws_security_group" "ssoon_sg" {
  vpc_id      = data.terraform_remote_state.db.outputs.vpcid
  name        = "T101 SG"
  description = "T101 Study SG"
}

resource "aws_security_group_rule" "ssoon_sginbound" {
  type              = "ingress"
  from_port         = 8080
  to_port           = 8080
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.ssoon_sg.id
}

resource "aws_security_group_rule" "ssoon_sgoutbound" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.ssoon_sg.id
}

userdata 파일 생성

user-data.sh
#!/bin/bash
wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64
mv busybox-x86_64 busybox
chmod +x busybox

cat > index.html <<EOF
<h1>T101 Study</h1>
<p>My RDS DB address: \${db_address}</p>
<p>My RDS DB port: \${db_port}</p>
EOF
nohup ./busybox httpd -f -p \${server_port} &

사용자 데이터 스크립트가 테라폼 코드에 임베드된 경우 테라폼은 참조와 보간을 이용하여 값을 채웁니다.

 String interpolation (문자열 보간) 이란 ?

  • 변수에 해당되는 값을 유동적으로 String에 넣을 수 있습니다.
  • 변수의 값이 바뀌어도 문자열 보간 방식을 통해 변한 값을 업데이트하여 출력할 수 있습니다. 
  • $ { 변수명 } 의 형식을 사용하면 문장에서 변수에 할당된 값이 들어가 출력되게 됩니다. 
const myNickname = 'Ssoon';
console.log(`My Nickname is ${myNickname}.`);
// Output: My Nickname is Ssoon.

 

 main.tf 에 ASG 코드 내용을 추가합니다.

templatefile(<PATH>, <VARS>)

하나의 프로그래밍 언어(Bash)를 다른 프로그래밍 언어(Terraform)에 포함하면 각 언어를 유지 관리하기가 어려워지므로 Bash 스크립트를 외부화하기 위해 templatefile 내장 함수를 사용할 수 있습니다.

 

이 함수는 PATH에서 파일을 읽고 템플릿으로 렌더링(renders)하고 결과를 문자열(string)로 반환합니다.
PATH의 파일이 Terraform(${...})에서 문자열 보간 구문(string interpolation syntax)을 사용할 수 있다는 것을 의미합니다.
Terraform은 해당 파일의 내용을 렌더링(renders)하여 VARS의 변수 참조를 채웁니다.

data "aws_ami" "ssoon__amazonlinux2" {
  most_recent = true
  filter {
    name   = "owner-alias"
    values = ["amazon"]
  }

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-ebs"]
  }

  owners = ["amazon"]
}

resource "aws_launch_configuration" "ssoon_lauchconfig" {
  name_prefix     = "t101-lauchconfig-"
  image_id        = data.aws_ami.ssoon__amazonlinux2.id
  instance_type   = "t2.micro"
  security_groups = [aws_security_group.ssoon_sg.id]
  associate_public_ip_address = true

  # Render the User Data script as a template
  user_data = templatefile("user-data.sh", {
    server_port = 8080
    db_address  = data.terraform_remote_state.db.outputs.address
    db_port     = data.terraform_remote_state.db.outputs.port
  })

  # Required when using a launch configuration with an auto scaling group.
  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_autoscaling_group" "ssoon_asg" {
  name                 = "ssoon_asg"
  launch_configuration = aws_launch_configuration.ssoon_lauchconfig.name
  vpc_zone_identifier  = [aws_subnet.ssoon_subnet1.id, aws_subnet.ssoon_subnet2.id]
  min_size = 2
  max_size = 10

  tag {
    key                 = "Name"
    value               = "terraform-asg"
    propagate_at_launch = true
  }
}

🚩 Console 확인

  • Launch configurations

  • Auto Scaling groups

 main.tf 에 ALB 코드 내용을 추가합니다.

resource "aws_lb" "ssoon_alb" {
  name               = "t101-alb"
  load_balancer_type = "application"
  subnets            = [aws_subnet.ssoon_subnet1.id, aws_subnet.ssoon_subnet2.id]
  security_groups    = [aws_security_group.ssoon_sg.id]

  tags = {
    Name = "t101-alb"
  }
}

resource "aws_lb_listener" "ssoon_http" {
  load_balancer_arn = aws_lb.ssoon_alb.arn
  port              = 8080
  protocol          = "HTTP"

  # By default, return a simple 404 page
  default_action {
    type = "fixed-response"

    fixed_response {
      content_type = "text/plain"
      message_body = "404: page not found - T101 Study"
      status_code  = 404
    }
  }
}

resource "aws_lb_target_group" "ssoon_albtg" {
  name     = "t101-alb-tg"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = data.terraform_remote_state.db.outputs.vpcid

  health_check {
    path                = "/"
    protocol            = "HTTP"
    matcher             = "200-299"
    interval            = 5
    timeout             = 3
    healthy_threshold   = 2
    unhealthy_threshold = 2
  }
}

resource "aws_lb_listener_rule" "ssoon_albrule" {
  listener_arn = aws_lb_listener.ssoon_http.arn
  priority     = 100

  condition {
    path_pattern {
      values = ["*"]
    }
  }

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.ssoon_albtg.arn
  }
}

output "ssoon_alb_dns" {
  value       = aws_lb.ssoon_alb.dns_name
  description = "The DNS Address of the ALB"
}

main.tf ASG 내용에 아래를 추가합니다.

resource "aws_autoscaling_group" "ssoon_asg" {
  health_check_type    = "ELB"
  target_group_arns    = [aws_lb_target_group.ssoon_albtg.arn]

🚩 Console 확인

  • Load balancer

  • HTTP:8080 listener

  • Target groups

  • Listener rules

📢 CLI 확인

 
Comments