[Terraform] count, output, 데이터 소스, 테라폼 클라우드

728x90

count

공식 문서: https://www.terraform.io/language/meta-arguments/count

count 를 사용하면 그 개수만큼 리소스가 생성된다.

resource "aws_instance" "server" {
  count = 4 # create four similar EC2 instances

  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"

  tags = {
    Name = "Server ${count.index}"
  }
}

떡하니 count 로 인스턴스 늘리는 게 끝이 아니라 해당 리소스와 관련된 모든 리소스에서 count 에 관련된 작업들을 해줘야 한다.

resource "aws_eip" "app_server_eip" {
  count = var.instance_count

  # aws_instance.app_server[0].id
  # aws_instance.app_server[1].id
  # 암시적 의존성
  instance = aws_instance.app_server[count.index].id
  vpc      = true
  tags     = local.common_tags
}

output 에서 count

output 블록에서는 count 알규먼트가 존재하지 않는다.

그 대신 *, 와일드 카드를 사용하여 각각의 리소스에 맵핑해줄 수 있다.

output "app_server_ip" {
  description = "app_server_ip"
  value       = aws_eip.app_server_eip.*.public_ip
}

output "app_server_public_ip" {
  value = aws_instance.app_server.*.public_ip
}

그러면 output 블록의 결과 값으로 아래 처럼 나온다.

Apply complete! Resources: 4 added, 0 changed, 2 destroyed.

Outputs:

app_server_ip = [
  "52.78.119.84",
  "52.78.20.80",
]
app_server_public_ip = [
  "13.124.250.236",
  "15.165.15.106",
]

데이터 소스

공식 문서: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami

프로바이더(aws, gcp, azure...) 에서 정보를 가져온다.

기본적으로 data 블록을 사용한다.

data "aws_ami" "example" {
  executable_users = ["self"]
  most_recent      = true             # 가장 최신 버전
  name_regex       = "^myami-\\\\d{3}"  # 검색할 이름을 정규표현식으로 나타냄
  owners           = ["self"]         # 필수값으로 누가 만들었는지를 나타냄

  filter {
    name   = "name"
    values = ["myami-*"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

위 이미지를 사용하고 싶을 때는 소유자, 루트 디바이스, 가상화, 이름 등 조건을 걸어주면 프로바이더에서 해당하는 객체를 가져온다.

data "aws_ami" "ubuntu_img" {
  owners      = ["099720109477"]
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

참조

resource "aws_instance" "app_server" {
  count = var.instance_count
  ami   = data.aws_ami.ubuntu_img.id
  # ami           = var.aws_amazon_linux_ami[var.aws_region]
  instance_type = var.instance.type
  subnet_id     = module.app_vpc.public_subnets[count.index % length(module.app_vpc.public_subnets)]

  key_name = aws_key_pair.app_server_key.key_name
}

state

공식 문서: https://www.terraform.io/language/state, https://www.terraform.io/language/settings/backends/configuration, https://www.terraform.io/language/settings/backends

상태를 저장하는 백엔드: https://www.terraform.io/language/settings/backends/s3, 버킷에 .tfstate 상태 파일을 저장한다.

locking: 데이터 공유할 때 데이터에 동시에 쓸 수 없도록 하는 메커니즘이다.

s3 에 스테이트를 저장하는 경우 s3 에는 locking 기능이 없어서 dynamoDB 를 사용할 수 있다.

테라폼 클라우드 기능이 나오고 난 이후에는 위와 같은 방법들이 시장됐다.

terraform cloud

workspaces 에서 상태 관리를 한다. 워크 스페이스를 만들고 terraform 블록에서 연결을 시켜준다. 원격 저장소에 .tfstate 파일이 저장되는 것이다.

  1. terraform login 실행, 홈페이지에서 토큰 생성 후에 해당 토큰을 붙여넣는다.
  2. .tf 파일에 아래 코드를 작성해주면 choi-dev 의 terraform-test 워크 스페이스에서 상태 관리를 하겠다는 뜻이다.

    현재는 git 에 연결하지 않았기 때문에 settings → general 에서 Execution Mode 를 Local 로 변경해줘야 한다.

 

  1. terraform init 실행
  2. terraform apply 실행

이제부터는 tfstate 파일들이 로컬에 저장되지 않고 terraform cloud 에 저장된다

terraform apply 혹은 destroy 를 실행하여 상태를 변경 시에는 아래 사진처럼 locking 이 걸린다.

실제로 모든 작업이 끝나면 locking 이 없어진 것을 볼 수 있다.

728x90