본문 바로가기!

Terraform

[Terraform] terraform_data 리소스 (null_resource 비교)

728x90
반응형

 

1. terraform_data 리소스 (null_resource 와의 비교점)

  • Terraform 1.4 버전이 릴리스되면서 기존의 null_resource를 대체하는 terraform_data 리소스가 추가되었습니다.
  • terraform_data는 null_resource와 달리 별도의 프로바이더 구성이 필요하지 않으며, 테라폼 자체에 포함된 기본 수명주기 관리자를 제공합니다.
  • null_resource와 terraform_data는 주로 Terraform 프로비저닝 동작을 설계하는 데 사용됩니다.
    • 이는 사용자가 의도적으로 프로비저닝 동작을 조율해야 하는 상황에서, 프로바이더가 제공하는 리소스 수명주기 관리만으로는 해결하기 어려울 때 유용합니다.
  • terraform_data 리소스는 임의의 값(input인수를 통해)을 저장하고 추후 다른 리소스의 수명 주기 트리거(강제 재실행을 위한 - trigger_replace)를 구현하는데 사용 가능하며, 적절한 관리 리소스를 사용할 수 없을 때 프로비저너를 트리거하는데 사용 가능합니다.

 

 

 

2. terraform_data 리소스와 trigger_replace 사용 예시

1. terraform_data 리소스와 trigger_replace를 사용한 테라폼 코드를 작성합니다.

resource "aws_network_interface" "ec2_private_ip" {
  subnet_id       = aws_subnet.pub_subnet.id
  private_ips     = ["192.168.1.11"]
  security_groups = [aws_security_group.apache_instance_sg.id]
  tags = {
    Name = "private_network_interface"
  }
}

resource "aws_eip" "apache_ec2_eip" {
  domain = "vpc"
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.latest_amazon_linux_2.id
  instance_type = "t2.micro"
  key_name      = var.key_pair_name

  network_interface {
    network_interface_id = aws_network_interface.ec2_private_ip.id
    device_index         = 0
  }

  tags = { Name = "${var.env}-instance" }
}

resource "aws_eip_association" "eip_assoc" {
  instance_id   = aws_instance.web.id
  allocation_id = aws_eip.apache_ec2_eip.id
}

resource "terraform_data" "ec2_trigger" {
  triggers_replace = [aws_instance.web.private_ip]

  provisioner "remote-exec" {
    connection {
      type        = "ssh"
      user        = "ec2-user"
      private_key = file("${path.module}/test.pem")
      host        = aws_eip.apache_ec2_eip.public_ip
    }
    inline = [
      "sudo yum update -y",
      "sudo yum install -y httpd",
      "sudo systemctl enable httpd",
      "sudo systemctl start httpd"
    ]
    
  }

  depends_on = [aws_eip_association.eip_assoc, aws_instance.web]
}

 

 

 

2. 코드 설명

  • terraform_data 리소스 내 remote-exec 프로비저너를 사용하여 ec2에 접속하여 apache를 설치합니다.
  provisioner "remote-exec" {
    connection {
      type        = "ssh"
      user        = "ec2-user"
      private_key = file("${path.module}/test.pem")
      host        = aws_eip.apache_ec2_eip.public_ip
    }
    inline = [
      "sudo yum update -y",
      "sudo yum install -y httpd",
      "sudo systemctl enable httpd",
      "sudo systemctl start httpd"
    ]
    
  }

 

 

  • terraform_data 리소스 내 triggers_replace를 활용하여 ec2의 private_ip가 바뀌었을때만 동작하도록 설정합니다.
  triggers_replace = [aws_instance.web.private_ip]

 

 

 

3. 결과 확인

 

  • 처음 테라폼 코드를 실행시킬 때는 network_interface의 private_ip를 192.168.1.11로 설정하여 실행합니다.
  • terraform_data 리소스 블럭의 triggers_replace를 주석 처리 하여 테라폼 재실행합니다.
    (아래와 같이 terraform_data 리소스 블럭의 remote-exec 프로비저너가 다시 실행되는 모습 확인 가능)
> terraform apply -auto-approve
data.aws_availability_zones.az: Reading...
aws_vpc.vpc: Refreshing state... [id=vpc-0bf92912f6a8cbe2b]
aws_eip.apache_ec2_eip: Refreshing state... [id=eipalloc-08123b33f6468c6bf]
data.aws_ami.latest_ubuntu_22_04: Reading...
data.aws_ami.latest_amazon_linux_2: Reading...
data.aws_availability_zones.az: Read complete after 0s [id=ap-northeast-2]
data.aws_ami.latest_ubuntu_22_04: Read complete after 0s [id=ami-0c0ea4662d3cca101]
data.aws_ami.latest_amazon_linux_2: Read complete after 0s [id=ami-0314c6b4d666713d7]
aws_internet_gateway.igw: Refreshing state... [id=igw-0a0216d3f5c6235bf]
aws_route_table.route_table_public: Refreshing state... [id=rtb-0847379a61cc54c4f]
aws_subnet.pub_subnet: Refreshing state... [id=subnet-0164714a54e2d3fb4]
aws_security_group.apache_instance_sg: Refreshing state... [id=sg-06d6207b06f4be11a]
aws_route.public_route: Refreshing state... [id=r-rtb-0847379a61cc54c4f1080289494]
aws_network_interface.ec2_private_ip: Refreshing state... [id=eni-0741b4d2b84d55f8b]
aws_route_table_association.public_asso_rt[0]: Refreshing state... [id=rtbassoc-05e30692a26bd21a7]
aws_instance.web: Refreshing state... [id=i-08c5cc8607b78d475]
aws_eip_association.eip_assoc: Refreshing state... [id=eipassoc-0eb1080611e176396]
terraform_data.ec2_trigger: Refreshing state... [id=730aff3b-3258-288c-d975-fc768362b2de]

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # terraform_data.ec2_trigger must be replaced
-/+ resource "terraform_data" "ec2_trigger" {
      ~ id               = "730aff3b-3258-288c-d975-fc768362b2de" -> (known after apply)
      - triggers_replace = [
          - "192.168.1.11",
        ] -> null
    }

Plan: 1 to add, 0 to change, 1 to destroy.
terraform_data.ec2_trigger: Destroying... [id=730aff3b-3258-288c-d975-fc768362b2de]
terraform_data.ec2_trigger: Destruction complete after 0s
terraform_data.ec2_trigger: Creating...
terraform_data.ec2_trigger: Provisioning with 'remote-exec'...
terraform_data.ec2_trigger (remote-exec): Connecting to remote host via SSH...
terraform_data.ec2_trigger (remote-exec):   Host: 52.78.93.204
terraform_data.ec2_trigger (remote-exec):   User: ec2-user
terraform_data.ec2_trigger (remote-exec):   Password: false
terraform_data.ec2_trigger (remote-exec):   Private key: true
terraform_data.ec2_trigger (remote-exec):   Certificate: false
terraform_data.ec2_trigger (remote-exec):   SSH Agent: true
terraform_data.ec2_trigger (remote-exec):   Checking Host Key: false
terraform_data.ec2_trigger (remote-exec):   Target Platform: unix
terraform_data.ec2_trigger (remote-exec): Connected!
terraform_data.ec2_trigger (remote-exec): Loaded plugins: extras_suggestions,
terraform_data.ec2_trigger (remote-exec):               : langpacks, priorities,
terraform_data.ec2_trigger (remote-exec):               : update-motd
terraform_data.ec2_trigger (remote-exec): No packages marked for update
terraform_data.ec2_trigger (remote-exec): Loaded plugins: extras_suggestions,
terraform_data.ec2_trigger (remote-exec):               : langpacks, priorities,
terraform_data.ec2_trigger (remote-exec):               : update-motd
terraform_data.ec2_trigger (remote-exec): Package httpd-2.4.57-1.amzn2.x86_64 already installed and latest version
terraform_data.ec2_trigger (remote-exec): Nothing to do
terraform_data.ec2_trigger: Creation complete after 3s [id=3cae2b7e-1c10-1f02-a77f-149f7761d033]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed

 

 

 

  • terraform_data 리소스 블럭의 triggers_replace를 주석 처리를 해제하여 테라폼 재실행
    (아래와 같이 terraform_data 리소스 블럭의 triggers_replace를 통해 aws_instance.web.private_ip가 변경될 때만 동작하기 때문에 remote-exec가 동작하지 않는 모습을 확인 가능)
> terraform apply -auto-approve
data.aws_availability_zones.az: Reading...
aws_eip.apache_ec2_eip: Refreshing state... [id=eipalloc-08123b33f6468c6bf]
data.aws_ami.latest_ubuntu_22_04: Reading...
aws_vpc.vpc: Refreshing state... [id=vpc-0bf92912f6a8cbe2b]
data.aws_ami.latest_amazon_linux_2: Reading...
data.aws_availability_zones.az: Read complete after 0s [id=ap-northeast-2]
data.aws_ami.latest_ubuntu_22_04: Read complete after 0s [id=ami-0c0ea4662d3cca101]
data.aws_ami.latest_amazon_linux_2: Read complete after 0s [id=ami-0314c6b4d666713d7]
aws_internet_gateway.igw: Refreshing state... [id=igw-0a0216d3f5c6235bf]
aws_route_table.route_table_public: Refreshing state... [id=rtb-0847379a61cc54c4f]
aws_subnet.pub_subnet: Refreshing state... [id=subnet-0164714a54e2d3fb4]
aws_security_group.apache_instance_sg: Refreshing state... [id=sg-06d6207b06f4be11a]
aws_route.public_route: Refreshing state... [id=r-rtb-0847379a61cc54c4f1080289494]
aws_route_table_association.public_asso_rt[0]: Refreshing state... [id=rtbassoc-05e30692a26bd21a7]
aws_network_interface.ec2_private_ip: Refreshing state... [id=eni-0741b4d2b84d55f8b]
aws_instance.web: Refreshing state... [id=i-08c5cc8607b78d475]
aws_eip_association.eip_assoc: Refreshing state... [id=eipassoc-0eb1080611e176396]
terraform_data.ec2_trigger: Refreshing state... [id=ad4dd631-d5f5-e8c8-75e6-288babf6bb57]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

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

 

728x90
반응형