나의 삽질 저장소!

Packer 변수 - 5편

by softPine

이전 튜토리얼에서는 템플릿을 사용하여 프로비저닝까지 진행했다. 그러나 템플릿 파일을 수정을 하려면 수동으로 다 작업을 해야 한다. 이러한 수동 작업 말고 변수를 활용하여 템플릿 파일 내부의 변경없이 값을 참조하는 방식으로 하여 템플릿 파일을 변경할 수 있다.

이번 튜로리얼에서는 Packer 빌드를 매개 변수화하여 편하게 사용할 수 있는 Packer 변수를 추가해본다.

 

사전 준비 사항

이전 튜토리얼까지 따라왔다면 추가적인 준비 사항은 없다.

추가적으로 Packer 템플릿 파일을 전체적으로 보여주면 다음과 같다.

packer {
  required_plugins {
    amazon = {
      version = ">= 0.0.1"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

source "amazon-ebs" "ubuntu" {
  ami_name      = "learn-packer-linux-aws-redis-msg"
  instance_type = "t2.micro"
  region        = "ap-northeast-2"
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"]
  }
  ssh_username = "ubuntu"
}

build {
  sources = [
    "source.amazon-ebs.ubuntu"
  ]

  provisioner "shell" {
    environment_vars = [
      "FOO=hello world",
    ]
    inline = [
      "echo Installing Redis",
      "sleep 30",
      "sudo apt-get update",
      "sudo apt-get install -y redis-server",
      "echo \"FOO is $FOO\" > example.txt",
    ]
  }

  provisioner "shell" {
    inline = ["echo This provisioner runs last"]
  }
}

 

템플릿에 변수 추가하기

Packer에는 두가지 타입의 변수가 있는데 입력 변수와 로컬 변수. 이번 섹션에서는 두 가지 타입의 변수를 사용해서 고유한 AMI 이름을 생성해 본다. 이렇게 하면 생성할 때 마다 이전처럼 AMI 이름을 변경할 필요가 없다.

 

입력 변수 추가

위의 aws-ubuntu.pkr.hcl 파일에 아래의 variable 블록을 추가한다.

variable "ami_prefix" {
  type    = string
  default = "learn-packer-linux-aws-redis"
}

위의 variable 블록은 변수 이름(ami_name), 데이터 타입(string)과 기본 값(learn-packer-linux-aws-redis)을 선언한다. 데이터 타입과 기본 값은 옵션이지만 새 변수를 만들 떄 이러한 속성을 정의하는 것이 좋다.

Packer는 변수를 상수로 취급한다. 즉, 실행 중 일때는 변경이 안된다.

 

로컬 변수 추가

입력변수와 같이 aws-ubuntu.pkr.hcl 파일에 아래의 local 블록을 추가한다.

locals {
  timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}

local 블록은 로컬 변수 이름(timestamp)과 값(regex_replace(timestamp(), "[- TZ:]", ""))을 선언한다. 로컬 변수는 일반적인 값들을 지정해야 할 때 유용하다. 

이번 Packer 예제에서는 함수(regex_replace)를 사용하여 타임 스탬프 로컬 변수를 변경하는 것을 한다.

입력변수와 마찬가지로 로컬 변수도 상수로 취급하여 실행 중 일 때는 업데이트를 할 수가 없다.

 

AMI 이름 변경하기

Packer 템플릿에서 ami_prefix  변수를 참조하도록 소스 블록을 업데이트해야 한다. 템플릿이 어떻게 변수를 var.ami_prefix로 참조하는지 확인한다.

source "amazon-ebs" "ubuntu" {
-  ami_name      = "learn-packer-linux-aws-redis-msg"
+  ami_name      = "${var.ami_prefix}-${local.timestamp}"
   ## ...
}

 

이미지 빌드하기

이미지를 빌드한다.

pk build .
amazon-ebs.ubuntu: output will be in this color.

==> amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> amazon-ebs.ubuntu: Prevalidating AMI Name: learn-packer-linux-aws-redis-20210608055831
    amazon-ebs.ubuntu: Found Image ID: ami-08508144e576d5b64
==> amazon-ebs.ubuntu: Creating temporary keypair: packer_60bf0707-aeff-28b1-bbba-ee7e70541fbd
==> amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_60bf0708-96c8-98cd-09f6-9912cfce355e
==> amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs.ubuntu: Launching a source AWS instance...
==> amazon-ebs.ubuntu: Adding tags to source instance
    amazon-ebs.ubuntu: Adding tag: "Name": "Packer Builder"
    amazon-ebs.ubuntu: Instance ID: i-0ac6443bf35ad1961
==> amazon-ebs.ubuntu: Waiting for instance (i-0ac6443bf35ad1961) to become ready...
==> amazon-ebs.ubuntu: Waiting for instance (i-0ac6443bf35ad1961) to become ready...
==> amazon-ebs.ubuntu: Using ssh communicator to connect: 3.35.27.6
==> amazon-ebs.ubuntu: Waiting for SSH to become available...
==> amazon-ebs.ubuntu: Connected to SSH!
==> amazon-ebs.ubuntu: Provisioning with shell script: /tmp/packer-shell681095097
    amazon-ebs.ubuntu: Installing Redis
==> amazon-ebs.ubuntu: Provisioning with shell script: /tmp/packer-shell859952608
    amazon-ebs.ubuntu: This provisioner runs last
==> amazon-ebs.ubuntu: Stopping the source instance...
    amazon-ebs.ubuntu: Stopping instance
==> amazon-ebs.ubuntu: Waiting for the instance to stop...
==> amazon-ebs.ubuntu: Creating AMI learn-packer-linux-aws-redis-20210608055831 from instance i-0ac6443bf35ad1961
    amazon-ebs.ubuntu: AMI: ami-07e47921463acc8a2
==> amazon-ebs.ubuntu: Waiting for AMI to become ready...
==> amazon-ebs.ubuntu: Terminating the source AWS instance...
==> amazon-ebs.ubuntu: Cleaning up any extra volumes...
==> amazon-ebs.ubuntu: No volumes to clean up, skipping
==> amazon-ebs.ubuntu: Deleting temporary security group...
==> amazon-ebs.ubuntu: Deleting temporary keypair...
Build 'amazon-ebs.ubuntu' finished after 5 minutes 2 seconds.

==> Wait completed after 5 minutes 2 seconds

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs.ubuntu: AMIs were created:
ap-northeast-2: ami-07e47921463acc8a2

Packer가 AMI 이름을 이전에 사용했던 입력 변수의 기본값 및 타임 스탬프로 구성된 AMI가 생성하는 과정을 볼 수 있다.

 

변수를 사용하여 이미지 빌드

변수를 할당하는 방법에는 여러가지 있다. 일단 우선순위는 CLI 플래그 값, 변수 파일, 환경 변수, 기본값의 순서이다. 이번에는 변수 파일과 CLI 플래그를 사용하여 변수를 정의한다.

 

변수 파일로 이미지 빌드하기

example.pkrvars.hcl 라는 변수 파일을 만들고 다음의 코드를 추가한다.

ami_prefix = "learn-packer-aws-redis-var"

이미지를 빌드하는데 --var-file 플래그를 사용한다.

pk build --var-file=example.pkrvars.hcl aws-ubuntu.pkr.hcl
amazon-ebs.ubuntu: output will be in this color.

==> amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> amazon-ebs.ubuntu: Prevalidating AMI Name: learn-packer-aws-redis-var-20210608060948
    amazon-ebs.ubuntu: Found Image ID: ami-08508144e576d5b64
==> amazon-ebs.ubuntu: Creating temporary keypair: packer_60bf09ac-1a1e-6ad7-12ea-95043835e239
==> amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_60bf09ad-1121-8a64-f0e0-63301d27af08
==> amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs.ubuntu: Launching a source AWS instance...
==> amazon-ebs.ubuntu: Adding tags to source instance
    amazon-ebs.ubuntu: Adding tag: "Name": "Packer Builder"
    amazon-ebs.ubuntu: Instance ID: i-0569d7c854a783204
==> amazon-ebs.ubuntu: Waiting for instance (i-0569d7c854a783204) to become ready...
==> amazon-ebs.ubuntu: Using ssh communicator to connect: 13.125.213.242
==> amazon-ebs.ubuntu: Waiting for SSH to become available...
==> amazon-ebs.ubuntu: Connected to SSH!
==> amazon-ebs.ubuntu: Provisioning with shell script: /tmp/packer-shell351205924
    amazon-ebs.ubuntu: Installing Redis
==> amazon-ebs.ubuntu: Provisioning with shell script: /tmp/packer-shell445778285
    amazon-ebs.ubuntu: This provisioner runs last
==> amazon-ebs.ubuntu: Stopping the source instance...
    amazon-ebs.ubuntu: Stopping instance
==> amazon-ebs.ubuntu: Waiting for the instance to stop...
==> amazon-ebs.ubuntu: Creating AMI learn-packer-aws-redis-var-20210608060948 from instance i-0569d7c854a783204
    amazon-ebs.ubuntu: AMI: ami-0fb2e7a6cf8bcef6e
==> amazon-ebs.ubuntu: Waiting for AMI to become ready...
==> amazon-ebs.ubuntu: Terminating the source AWS instance...
==> amazon-ebs.ubuntu: Cleaning up any extra volumes...
==> amazon-ebs.ubuntu: No volumes to clean up, skipping
==> amazon-ebs.ubuntu: Deleting temporary security group...
==> amazon-ebs.ubuntu: Deleting temporary keypair...
Build 'amazon-ebs.ubuntu' finished after 3 minutes 47 seconds.

==> Wait completed after 3 minutes 47 seconds

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs.ubuntu: AMIs were created:
ap-northeast-2: ami-0fb2e7a6cf8bcef6e

이미지 빌드를 할 때 변수 파일에 할당된 learn-packer-aws-redis-var- 로 시작하는 AMI명을 확인한다.

또한 Packer는 CLI 를 통해 변수 파일을 전달할 필요 없이 *.auto.pkvars.hcl 이름과 일치하는 모든 변수 파일을 자동으로 로드한다.

Packer가 자동으로 로드 하도록 변수 파일의 이름을 변경해본다.

mv example.pkrvars.hcl example.auto.pkrvars.hcl

이후 다시 이미지를 빌드하는데 기존과 같이 packer build . 명령어만 사용해서 변수값이 로드되는지 확인한다.

pk build .
amazon-ebs.ubuntu: output will be in this color.

==> amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> amazon-ebs.ubuntu: Prevalidating AMI Name: learn-packer-aws-redis-var-20210608061403
    amazon-ebs.ubuntu: Found Image ID: ami-08508144e576d5b64
...
==> amazon-ebs.ubuntu: Creating AMI learn-packer-aws-redis-var-20210608061403 from instance i-0733afdf72701399a
    amazon-ebs.ubuntu: AMI: ami-01789f0772de83824
==> amazon-ebs.ubuntu: Waiting for AMI to become ready...
...

 

CLI 플래그를 사용하여 이미지 빌드하기

CLI 플래그에 직접 변수를 설정하여 이미지를 빌드한다.

pk build --var ami_prefix=learn-packer-aws-redis-var-flag .
amazon-ebs.ubuntu: output will be in this color.

==> amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> amazon-ebs.ubuntu: Prevalidating AMI Name: learn-packer-aws-redis-var-flag-20210608062204
    amazon-ebs.ubuntu: Found Image ID: ami-08508144e576d5b64
==> amazon-ebs.ubuntu: Creating temporary keypair: packer_60bf0c8c-5870-dc1b-79ce-49dcde9b1f3d
==> amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_60bf0c8d-7df0-022e-9dd9-6cd954bde51a
==> amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs.ubuntu: Launching a source AWS instance...
==> amazon-ebs.ubuntu: Adding tags to source instance
    amazon-ebs.ubuntu: Adding tag: "Name": "Packer Builder"
    amazon-ebs.ubuntu: Instance ID: i-009a5025dde1b405f
==> amazon-ebs.ubuntu: Waiting for instance (i-009a5025dde1b405f) to become ready...
==> amazon-ebs.ubuntu: Creating AMI learn-packer-aws-redis-var-flag-20210608062204 from instance i-009a5025dde1b405f
    amazon-ebs.ubuntu: AMI: ami-0e7709756e390ce6f
==> amazon-ebs.ubuntu: Waiting for AMI to become ready...

AMI 이름이 learn-packer-aws-redis-var-flag로 시작하는 걸 확인한다. CLI 플래그는 가장 높은 우선 순위를 가지며 다른 메서드에서 정의한 값을 재정의를 한다.

'OpenSource > Packer' 카테고리의 다른 글

Packer 병렬 빌드 - 6편  (0) 2021.06.09
Packer로 프로비저닝하기 - 4편  (0) 2021.06.07
Packer로 이미지 만들어보기 - 3편  (0) 2021.06.06
Packer 설치 - 2편  (0) 2021.06.04
Packer란? - 1편  (0) 2021.06.04

블로그의 정보

나의 삽질저장소

softPine

활동하기