IaC/Infrastructure Provisioning

Packer란?

Somaz 2022. 9. 5. 16:54
728x90
반응형

Overview

HashiCorp의 Packer에 대해서 공부해보려고 한다.

이전 게시글인 Vagrant에 사용할 image box를 Packer를 이용해서 만들어 볼것이다.

2022.08.25 - [Understand different OS Concepts/Virtualization] - Vagrant란?

 

Vagrant란?

overview 오늘은 Vagrant에 대해서 공부해보려고 한다. Vagrant란? Vagrant는 단일 워크플로에서 가상 머신 환경을 구축하고 관리하기 위한 도구입니다. Provisioning 기능을 통하여 요구 사항에 맞는 가상

somaz.tistory.com

 

https://github.com/somaz94/vagant-packer

 

GitHub - somaz94/vagant-packer: This is Vagrant and Packer Collection

This is Vagrant and Packer Collection. Contribute to somaz94/vagant-packer development by creating an account on GitHub.

github.com

 


Packer란?

Packer 는 단일 소스 템플릿에서 여러 플랫폼에 대해 동일한 머신 이미지를 생성할 수 있는 오픈 소스 도구이다. 

일반적인 사용 사례는 조직 전체의 팀이 클라우드 인프라에서 사용할 수 있는 "Golden image"를 만드는 것다.

 

Packer 패키지 설치

# CentOS/RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install vagrant
sudo yum -y install qemu libvirt libvirt-devel ruby-devel gcc qemu-kvm libguestfs-tools
vagrant plugin install vagrant libvirt
vagrant plugin install vagrant-mutate
vagrant plugin install vagrant-parallels

# Ubuntu/Debian
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vagrant
sudo apt install -y qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager
vagrant plugin install vagrant libvirt
vagrant plugin install vagrant-mutate
vagrant plugin install vagrant-parallels

 

Packer CLI 자동완성

packer -autocomplete-install

 

Packer error 조치(명령어 error)

packer --help
Usage:  packer dbname
  if dbname is not specified, will use compiled in default of (/usr/share/cracklib/pw_dict).
  
cd /usr/sbin/

ls -al |grep packer
-rwxr-xr-x.  1 root root       11328 Jun 10  2014 cracklib-packer
-rwxr-xr-x.  1 root root        7184 Jun 10  2014 cracklib-unpacker
lrwxrwxrwx.  1 root root          15 Feb 10  2022 packer -> cracklib-packer

rm -rf packer
ln -s /usr/bin/packer packer
packer
Usage: packer [--version] [--help] <command> [<args>]

Available commands are:
    build           build image(s) from template
    console         creates a console for testing variable interpolation
    fix             fixes templates from old versions of packer
    fmt             Rewrites HCL2 config files to canonical format
    hcl2_upgrade    transform a JSON template into an HCL2 configuration
    init            Install missing plugins or upgrade plugins
    inspect         see components of a template
    plugins         Interact with Packer plugins and catalog
    validate        check that a template is valid
    version         Prints the Packer version

 


Packer CLI

 

init

  •  Packer 플러그인 바이너리를 다운로드 사용
$ packer init -h
Usage: packer init [options] [config.pkr.hcl|folder/]

  Install all the missing plugins required in a Packer config. Note that Packer
  does not have a state.

  This is the first command that should be executed when working with a new
  or existing template.

  This command is always safe to run multiple times. Though subsequent runs may
  give errors, this command will never delete anything.

Options:
  -upgrade                     On top of installing missing plugins, update
                               installed plugins to the latest available
                               version, if there is a new higher one. Note that
                               this still takes into consideration the version
                               constraint of the config.

 

plugins

  • Packer 플러그인과 상호 작용하기 위한 하위 명령을 그룹화
packer plugins -h
Usage: packer plugins <subcommand> [options] [args]
  This command groups subcommands for interacting with Packer plugins.

Related but not under the "plugins" command :

- "packer init <path>" will install all plugins required by a config.

Subcommands:
    install      Install latest Packer plugin [matching version constraint]
    installed    List all installed Packer plugin binaries
    remove       Remove Packer plugins [matching a version]
    required     List plugins required by a config

 

build

  • packer build 명령은 템플릿을 사용하고 아티팩트 집합을 생성하기 위해 템플릿 내의 모든 빌드를 실행합니다.
packer build -h
Usage: packer build [options] TEMPLATE

  Will execute multiple builds in parallel as defined in the template.
  The various artifacts created by the template will be outputted.

Options:

  -color=false                  Disable color output. (Default: color)
  -debug                        Debug mode enabled for builds.
  -except=foo,bar,baz           Run all builds and post-processors other than these.
  -only=foo,bar,baz             Build only the specified builds.
  -force                        Force a build to continue if artifacts exist, deletes existing artifacts.
  -machine-readable             Produce machine-readable output.
  -on-error=[cleanup|abort|ask|run-cleanup-provisioner] If the build fails do: clean up (default), abort, ask, or run-cleanup-provisioner.
  -parallel-builds=1            Number of builds to run in parallel. 1 disables parallelization. 0 means no limit (Default: 0)
  -timestamp-ui                 Enable prefixing of each ui output with an RFC3339 timestamp.
  -var 'key=value'              Variable for templates, can be used multiple times.
  -var-file=path                JSON or HCL2 file containing user variables.

 

packer build somaz-os-test.vagrant.json
somaz-os-test: output will be in this color.

 

이 외에도 console, fix, fmt, inspect, validate, hcl2_upgrade 등이있다.

 


Packer Template

Packer의 동작은 Packer가 따를 일련의 선언과 명령으로 구성된 Packer 템플릿에 의해 결정된다.

Packer는 과거에는 JSON 템플릿을 사용했지만, Terraform 및 HashiCorp의 다른 제품에서 사용하는 것과 동일한 구성 언어인 HCL2를 사용하는 새로운 템플릿 구성 형식으로 전환하고 있다.

해당 형식은 원래 JSON 템플릿 형식보다 더 유연하고 모듈식이며 간결하다.

JSON 형식은 계속 지원되지만 Packer 코어의 특정 새 기능은 최신 HCL 형식에 대해서만 구현된다.

 


 

 

HCL 형식

HCL 언어의 구문은 다음과 같은 몇 가지 기본 요소로만 구성된다.

# This file was autogenerated by the 'packer hcl2_upgrade' command. We
# recommend double checking that everything is correct before going forward. We
# also recommend treating this file as disposable. The HCL2 blocks in this
# file can be moved to other files. For example, the variable blocks could be
# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be
# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at
# once they also need to be in the same folder. 'packer inspect folder/'
# will describe to you what is in that folder.

# Avoid mixing go templating calls ( for example ```{{ upper(`string`) }}``` )
# and HCL2 calls (for example '${ var.string_value_example }' ). They won't be
# executed together and the outcome will be unknown.

# See https://www.packer.io/docs/templates/hcl_templates/blocks/packer for more info
packer {
  required_plugins {
    amazon = {
      source  = "github.com/hashicorp/amazon"
      version = "~> 1"
    }
  }
}

# All generated input variables will be of 'string' type as this is how Packer JSON
# views them; you can change their type later on. Read the variables type
# constraints documentation
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.
variable "cpu" {
  type    = string
  default = "2"
}

variable "instance_type" {
  type    = string
  default = "t2.micro"
}

variable "ram" {
  type    = string
  default = "2048"
}

variable "region" {
  type    = string
  default = "ap-northeast-2"
}

variable "user" {
  type    = string
  default = "ec2-user"
}

variable "password" {
  type    = string
  default = "somaz@2023"
}

# The amazon-ami data block is generated from your amazon builder source_ami_filter; a data
# from this block can be referenced in source and locals blocks.
# Read the documentation for data blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
# Read the documentation for the Amazon AMI Data Source here:
# https://www.packer.io/plugins/datasources/amazon/ami
data "amazon-ami" "autogenerated_1" {
  filters = {
    name                = "amzn2-ami-hvm-*-x86_64-gp2"
    root-device-type    = "ebs"
    virtualization-type = "hvm"
  }
  most_recent = true
  owners      = ["amazon"]
  region      = "${var.region}"
}

# "timestamp" template function replacement
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }

# source blocks are generated from your builders; a source can be referenced in
# build blocks. A build block runs provisioner and post-processors on a
# source. Read the documentation for source blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/source
source "amazon-ebs" "autogenerated_1" {
  ami_name         = "amazon-linux2-golden-image ${local.timestamp}"
  force_deregister = true
  instance_type    = "${var.instance_type}"
  region           = "${var.region}"
  source_ami       = "${data.amazon-ami.autogenerated_1.id}"
  ssh_interface    = "public_ip"
  ssh_username     = "${var.user}"
  tags = {
    Name = "Amazon Linux 2 Golden Image"
  }
}

# a build block invokes sources and runs provisioning steps on them. The
# documentation for build blocks can be found here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
build {
  sources = ["source.amazon-ebs.autogenerated_1"]

  provisioner "shell" {
    execute_command = "echo ' ${var.password}' | {{ .Vars }} sudo -E -S bash '{{ .Path }}'"
    scripts         = ["scripts/package.sh"]
  }

}

 


 

JSON 형식

 

Json 템플릿

템플릿은 Packer의 다양한 구성 요소를 구성하는 키 집합이 있는 JSON 개체입니다. 

템플릿 내에서 사용 가능한 키가 아래에 나열되어 있습니다. 각 키와 함께 필수 여부가 표시됩니다.

 

Json 템플릿 구조

{
    "variables": {
        "cpu": "2",
        "ram": "2048",
        "user": "ec2-user",
        "region": "ap-northeast-2",
        "instance_type": "t2.micro"
    },

    "builders": [
        {
            "type": "amazon-ebs",
            "region": "{{user `region`}}",
            "source_ami_filter": {
                "filters": {
                    "virtualization-type": "hvm",
                    "name": "amzn2-ami-hvm-*-x86_64-gp2",
                    "root-device-type": "ebs"
                },
                "owners": ["amazon"],
                "most_recent": true
            },
            "instance_type": "{{user `instance_type`}}",
            "ssh_username": "{{user `user`}}",
            "ami_name": "amazon-linux2-golden-image {{timestamp}}",
            "ssh_interface": "public_ip",
            "force_deregister": true,
            "tags": {
                "Name": "Amazon Linux 2 Golden Image"
            }
        }
    ],

    "provisioners": [
        {
            "type": "shell",
            "execute_command": "echo ' {{user `password`}}' | {{.Vars}} sudo -E -S bash '{{.Path}}'",
            "scripts": [
                "scripts/package.sh"
            ]
        }
    ]
}
  • builders( 필수 ​​)는 이 템플릿에 대한 머신 이미지를 생성하는 데 사용할 빌더를 정의하고 해당 빌더 각각을 구성하는 하나 이상의 객체 배열입니다. 자세한 내용 은 템플릿에서 빌더 구성 에 대한 하위 섹션을 참조해보자.
  • variables(선택 사항) 템플릿에 포함된 사용자 변수를 정의하는 하나 이상의 키/값 문자열의 개체입니다.자세한 내용 은 템플릿의 사용자 변수에 대한 하위 섹션을 참조해보자. 
  • provisioners(선택 사항) 각 빌더가 생성한 시스템에 대한 소프트웨어를 설치 및 구성하는 데 사용할 프로비저닝 도구를 정의하는 하나 이상의 개체 배열입니다. 자세한 내용 은 템플릿에서 프로비저닝 도구 구성 에 대한 하위 섹션을 참조해보자.
  • post-processors(선택 사항) 빌드된 이미지와 함께 수행할 다양한 사후 처리 단계를 정의하는 하나 이상의 개체 배열입니다. 자세한 내용은 템플릿에서 포스트 프로세서 구성 에 대한 하위 섹션을 참조해보자.

 


Packer JSON 템플릿을 HCL2 업그레이드

Packer는 hcl2_upgrade 명령을 사용하여 기존 Packer  JSON 템플리을 HCL2로 전환할 수 있다.

​자세한 내용은 Github 링크를 참조하면 된다.

 


 

ubuntu-gce.json

{
    "variables": {
        "project_id": "somaz", 					
        "source_image_family": "ubuntu-2004-lts",
        "zone": "asia-northeast3-a", 				
        "machine_type": "n1-standard-1", 			
        "account_file": "/home/somaz/.ssh/somaz-key.json",
        "password" : "somaz@2023"
    },

    "builders": [
        {
            "type": "googlecompute",
            "project_id": "{{user `project_id`}}",
            "source_image_family": "{{user `source_image_family`}}",
            "zone": "{{user `zone`}}",
            "machine_type": "{{user `machine_type`}}",
            "ssh_username": "ubuntu",
            "image_name": "ubuntu-golden-image-{{timestamp}}",
            "image_description": "Ubuntu Golden Image",
            "disk_type": "pd-ssd",
            "disk_size": "10",
            "network": "default",
            "subnetwork": "default",
            "tags": ["ubuntu", "golden-image"],
            "use_internal_ip": false,
            "account_file": "{{user `account_file`}}"
        }
    ],

    "provisioners": [
        {
            "type": "shell",
            "execute_command": "echo '{{user `password`}}' | {{.Vars}} sudo -E -S bash '{{.Path}}'",
            "scripts": [
                "scripts/ubuntu-setup.sh"
            ]
        }
    ]
}

 

Packer JSON 템플릿을 HCL2 업그레이드한다.

packer hcl2_upgrade -with-annotations ubuntu-gce.json
Successfully created ubuntu-gce.json.pkr.hcl

 

ubuntu-gce.json.pkr.hcl

# This file was autogenerated by the 'packer hcl2_upgrade' command. We
# recommend double checking that everything is correct before going forward. We
# also recommend treating this file as disposable. The HCL2 blocks in this
# file can be moved to other files. For example, the variable blocks could be
# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be
# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at
# once they also need to be in the same folder. 'packer inspect folder/'
# will describe to you what is in that folder.

# Avoid mixing go templating calls ( for example ```{{ upper(`string`) }}``` )
# and HCL2 calls (for example '${ var.string_value_example }' ). They won't be
# executed together and the outcome will be unknown.

# See https://www.packer.io/docs/templates/hcl_templates/blocks/packer for more info
packer {
  required_plugins {
    googlecompute = {
      source  = "github.com/hashicorp/googlecompute"
      version = "~> 1"
    }
  }
}

# All generated input variables will be of 'string' type as this is how Packer JSON
# views them; you can change their type later on. Read the variables type
# constraints documentation
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.
variable "account_file" {
  type    = string
  default = "/home/somaz/.ssh/somaz.json"
}

variable "machine_type" {
  type    = string
  default = "n1-standard-1"
}

variable "project_id" {
  type    = string
  default = "somaz"
}

variable "source_image_family" {
  type    = string
  default = "ubuntu-2004-lts"
}

variable "zone" {
  type    = string
  default = "asia-northeast3-a"
}

variable "password" {
  type    = string
  default = "somaz@2023"
}

# "timestamp" template function replacement
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }

# source blocks are generated from your builders; a source can be referenced in
# build blocks. A build block runs provisioner and post-processors on a
# source. Read the documentation for source blocks here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/source
source "googlecompute" "autogenerated_1" {
  account_file        = "${var.account_file}"
  disk_size           = "10"
  disk_type           = "pd-ssd"
  image_description   = "Ubuntu Golden Image"
  image_name          = "ubuntu-golden-image-${local.timestamp}"
  machine_type        = "${var.machine_type}"
  network             = "default"
  project_id          = "${var.project_id}"
  source_image_family = "${var.source_image_family}"
  ssh_username        = "ubuntu"
  subnetwork          = "default"
  tags                = ["ubuntu", "golden-image"]
  use_internal_ip     = false
  zone                = "${var.zone}"
}

# a build block invokes sources and runs provisioning steps on them. The
# documentation for build blocks can be found here:
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
build {
  sources = ["source.googlecompute.autogenerated_1"]

  provisioner "shell" {
    execute_command = "echo '${var.password}' | {{ .Vars }} sudo -E -S bash '{{ .Path }}'"
    scripts         = ["scripts/ubuntu-setup.sh"]
  }

}

 


 

 Reference

https://www.packer.io/docs

https://youngswooyoung.tistory.com/176

https://github.com/chef/bento 

https://github.com/somaz94/vagant-packer

https://developer.hashicorp.com/packer/tutorials/configuration-language/hcl2-upgrade

728x90
반응형