HashiCorp/Packer

Packer(1)

backtwobasic 2025. 1. 19. 19:23

Packer

Hashicorp 에서 제공하는 IaC 오픈소스 도구 중 하나. Multi Cloud platform에서 동일한 이미지, 즉 서버 이미지 생성을 자동화 할 수 있도록 도와주는 오픈소스이다. AWS, Azure, GCP 등 다양한 플랫폼에서 사용할 수 있는 이미지를 동적으로 사용 가능하게 한다. 이를 Hashicorp에서는 "Golden Image"를 만드는 자동화 도구라고 설명하고 있다. 

 

Packer 의 장점

첫 번째로 신속한 인프라 구축이 가능하다는 점이다. Terraform 과 연계해서 몇 초 내에 Packer로 생성한 이미지를 프로비저닝하여 인스턴스를 시작할 수 있도록 해준다. 

 

두번째로 Multi Provider 이식성에서 효율이 좋다. 동일한 이미지를 사용하여 AWS, Azure, GCP, VMware 등 다양한 플랫폼에서 환경 별로 인스턴스를 실행할 수 있다. 어떠한 플랫폼에서 코드를 기반으로 일관되게 VM과 Container 이미지 템플릿을 적용할 수 있도록 한다. 

 

세번째로 Gitops에 부합하는 소스 기반 서비스로 빌드가 진행되기 때문에, 선언형 모델의 성질을 띄고 있어 빠르고 가시성 있다. 재사용이 가능하고 추적 가능한 이미지 빌드가 가능하다. 

 

 

Packer 구성요소

Packer는 Template이라는 소스 코드를 담은 파일을 통해 동작한다. 일반적으로 Packer Template이 작성된 방식 즉, json 파일로 작성되었는지, 또는 hcl2 파일로 작성되었는지에 따라 구성요소가 달라진다. 

(1) Packer Template 이 Hcl2 형식일 경우

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

source "amazon-ebs" "example" {
  region           = "us-west-2"
  source_ami       = "ami-0abcdef1234567890"
  instance_type    = "t2.micro"
  ssh_username     = "ubuntu"
  ami_name         = "example-ami-${timestamp()}"
}

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


hcl2 는 HashiCorp Configuration Language 2의 약자로, json 형식보다 더 직관적이고 모듈화하기에 적합하다. hcl2 형식으로 template을 작성할 경우, 가독성이 높고, 재사용이 가능한 모듈화를 지원한다. 또 조건문 및 반복문과 같은 동적 구성이 가능하고, packer block을 활용한 플러그인 및 버전 제약 관리가 가능하다는 특징이 있다. hcl2 형식으로 template을 작성할 경우, packer block, variable block, source block, build block, provisioner block 등이 있다. 

 

먼저 Packer Block 이다. Packer 플러그인의 요구사항, 버전 및 관련 메타데이타를 정의하는 부분이다. 

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

 

두 번째는 Variable Block 이다. template 내에서 사용할 수 있는 변수를 정의하는 부분으로 변수 값은 명령줄, 환경 변수, 파일 등에서 제공된다. 

variable "region" {
  type    = string
  default = "us-west-2"
}

variable "ami_name" {
  type    = string
  default = "example-ami-${timestamp()}"
}

source "amazon-ebs" "example" {
  region     = var.region
  ami_name   = var.ami_name
}

 

세 번째는 source block 이다. 이미지를 빌드하기 위한 소스를 정의하는 블록으로, builder에 따라 설정 내용이 달라진다. 

source "amazon-ebs" "example" {
  region        = var.region
  source_ami    = "ami-0abcdef1234567890"
  instance_type = "t2.micro"
  ssh_username  = "ubuntu"
  ami_name      = var.ami_name
}

 

build block 은 source block을 참조하여 이미지 빌드 과정을 정의하는 부분이다. 

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

  provisioner "shell" {
    inline = ["echo 'Hello, world!'"]
  }
}

 

마지막으로 provisioner block 은 이미지 빌드 과정에서 스크립트나 명령 실행을 담당하는 부분이다. 

provisioner "shell" {
  inline = [
    "sudo apt-get update",
    "sudo apt-get install -y nginx"
  ]
}

 

(2) Packer Template 이 json 형식일 경우

먼저 json 형식을 보면 다음과 같다. 

{
  "variables": {
    "region": "us-west-2",
    "source_ami": "ami-0abcdef1234567890",
    "instance_type": "t2.micro",
    "ami_name": "example-ami-{{timestamp}}"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "region": "{{user `region`}}",
      "source_ami": "{{user `source_ami`}}",
      "instance_type": "{{user `instance_type`}}",
      "ssh_username": "ubuntu",
      "ami_name": "{{user `ami_name`}}",
      "launch_block_device_mappings": [
        {
          "device_name": "/dev/xvda",
          "volume_size": 8,
          "volume_type": "gp2",
          "delete_on_termination": true
        }
      ]
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "sudo apt-get update",
        "sudo apt-get install -y nginx",
        "sudo systemctl enable nginx"
      ]
    },
    {
      "type": "shell",
      "inline": [
        "echo 'Welcome to your new server!' > /var/www/html/index.html"
      ]
    }
  ]
}

 

json 형식으로 작성할 경우, 설정 파일 구성이 익숙할 수 있고, 간단한 템플릿을 작성하기에 적합하다는 장점이 있지만, 복잡한 형태의 인프라를 구성할 경우에는 적합하지 않을 수 있다. 또 조건문, 반복문 같은 동적 구성이 불가능하고 가독성이 떨어질 수 있다는 단점이 있다. 

 

 

Packer Workflow 

packer를 활용할 경우 흐름을 정리하면 5단계 정도로 설명할 수 있을 것이다.

 

(1) template 정의

위에서 미리 설명한 json, 또는 hcl2 형식으로 build template 을 작성한다. 여기에 builder(이미지를 생성할 환경), provisioner(설치 또는 설정 작업), 변수 등이 포함된다. 

 

(2) builder 실행

정의된 builder 를 기반으로 인스턴스를 생성한다. 이 때 builder는 AWS, Azure, Docker 등 다양한 플랫폼을 지원한다. 

 

(3) provisioning

provisioner 를 사용해 소프트웨어 설치, 설정 스크립트 실행 등을 통해 이미지에 필요한 구성을 적용한다. 

 

(4) 이미지 생성

provisioning 이 완료된 후, 최종 이미지를 생성하고 저장한다. 이 떄 생성된 이미지는 AWS ami, Docker 이미지 등과 같은 다양한 포맷으로 제공된다. 

 

(5) 배포 또는 테스트

생성된 이미지를 배포하거나 테스트 환경에서 사용한다. 이 과정에서 인프라 자동화 도구 중에 하나인 Terraform, Ansible 등과 연동할 수 있다. 

 

https://developer.hashicorp.com/hcp/docs/packer