본문 바로가기

IaC/Packer

[Packer]AWS AMI Build with Ansible provisioner

아래 글에서는 Packer와 Ansible을 사용하여 Nginx를 포함한 t2.micro Amazon EC2 AMI를 빌드하는 방법을 소개합니다.

Packer란?

Packer는 HashiCorp에서 개발한 오픈 소스 도구로, 클라우드나 가상화 플랫폼에서 사용할 이미지를 자동으로 생성합니다. Packer는 여러 플랫폼을 지원하며, AWS EC2 AMI와 같은 이미지를 생성할 수 있습니다.

Installing Packer

https://developer.hashicorp.com/packer/downloads

brew tap hashicorp/tap
brew install hashicorp/tap/packer
brew upgrade hashicorp/tap/packer

Verifying the Installation

➜ 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 구성 파일과 Ansible 역할 및 플레이북의 디렉토리 구조입니다.

.
├── ansible
│   ├── ansible.cfg
│   ├── main.yml
│   ├── roles
│   │   └── common
│   │       ├── handlers
│   │       │   └── main.yml
│   │       ├── tasks
│   │       │   └── main.yml
│   │       ├── templates
│   │       │   └── nginx.conf.j2
│   │       └── vars
│   │           └── main.yml
│   └── vars
│       └── main.yaml
├── packer
│   ├── main.pkr.hcl
│   ├── packer.pkrvars.hcl
│   └── variables.pkr.hcl

Write Packer template

Packer 템플릿을 작성하여 AMI를 빌드합니다. 아래는 t3.micro 인스턴스 유형을 사용하는 Amazon EBS 기반 AMI의 예시입니다. 이 예제에서는 Packer의 Amazon EBS 빌더와 Ansible 프로비저닝을 사용합니다.

# "Build SQL Runner v2 Worker AMI"
packer {
  required_plugins {
    amazon = {
      source  = "github.com/hashicorp/amazon"
      version = "~> 1"
    }
    ansible = {
      source  = "github.com/hashicorp/ansible"
      version = "~> 1"
    }
  }
}

source "amazon-ebs" "ubuntu" {
  ami_name           = "learn-packer-linux-aws-from-jeff"
  instance_type      = "t3.micro"
  region             = "ap-northeast-2"
  vpc_id             = "vpc-0f#"
  subnet_id          = "subnet-04#" 
  security_group_ids = ["sg-01#"]
  ssh_username       = ubuntu
  tags               = local.common_tags
  ami_users = [
    "your aws account"
  ]

  source_ami_filter {
    filters = {
      name                = "ubuntu/images/hvm-ssd/*ubuntu-jammy-22.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"] # ubuntu official accounts
  }

}

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

  provisioner "ansible" {
    playbook_file = "../ansible/main.yml"
    extra_arguments = [
      "--scp-extra-args", "'-O'"
    ]
  }

}

vpc, subnet id를 작성해야한다. 특정 서브넷을 작성하여 ami를 생성하고 이후에 해당 ami로 asg 설정 시 여러 서브넷을 명시할 수 있습니다.

source ami 확인하는 방법

aws ec2 describe-images --owners 099720109477 --query 'sort_by(Images, &CreationDate)[*].[CreationDate,Name,ImageId]' --filters "Name=name,Values=ubuntu*" --region ap-northeast-2 --output table

Packer Block

블록 packer {}에는 필수 Packer 버전 지정을 포함한 Packer 설정이 포함되어 있습니다.

source Block

블록 source은 특정 빌더  플러그인을 구성한 다음 build블록에 의해 호출됩니다.

build

블록 build은 Packer가 시작된 후 EC2 인스턴스로 수행해야 하는 작업을 정의합니다.

Ansible

[Ansible]Nginx 설치하기 with tasks, handlers, templates, vars

Configure aws credentials

export AWS_ACCESS_KEY_ID="<YOUR_AWS_ACCESS_KEY_ID>"
export AWS_SECRET_ACCESS_KEY="<YOUR_AWS_SECRET_ACCESS_KEY>"

Initialize Packer configuration

➜ packer init .
Installed plugin github.com/hashicorp/amazon v1.2.7 in "/Users/jeff/.config/packer/plugins/github.com/hashicorp/amazon/packer-plugin-amazon_v1.2.7_x5.0_darwin_arm64"

Format and validate your Packer template

Packer 구성 초기화 및 검증

➜ packer fmt . 
aws-ubuntu.pkr.hcl

➜ packer validate .
The configuration is valid.

Build Packer image

Packer를 사용하여 AMI를 빌드합니다. 아래 명령어를 실행하여 AMI 빌드 과정을 시작합니다.

이 과정에서 Packer는 EC2 인스턴스를 생성하고, Ansible 프로비저너를 통해 Nginx를 설치한 후, AMI를 생성합니다.

➜ packer fmt .                   
aws-ubuntu.pkr.hcl
➜ packer build aws-ubuntu.pkr.hcl
learn-packer.amazon-ebs.ubuntu: output will be in this color.

==> learn-packer.amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> learn-packer.amazon-ebs.ubuntu: Prevalidating AMI Name: learn-packer-linux-aws-from-jeff
    learn-packer.amazon-ebs.ubuntu: Found Image ID: ami-0a83adc173863d831
==> learn-packer.amazon-ebs.ubuntu: Creating temporary keypair: packer_65360b62-a076-7ac6-5d82-0d12754f63d5
==> learn-packer.amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_65360b64-a1e5-9cbd-ea78-819c3ee43928
==> learn-packer.amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> learn-packer.amazon-ebs.ubuntu: Launching a source AWS instance...
    learn-packer.amazon-ebs.ubuntu: Instance ID: i-0ca3d8db7ad97eebe
==> learn-packer.amazon-ebs.ubuntu: Waiting for instance (i-0ca3d8db7ad97eebe) to become ready...
==> learn-packer.amazon-ebs.ubuntu: Using SSH communicator to connect: 10.77.110.112
==> learn-packer.amazon-ebs.ubuntu: Waiting for SSH to become available...
==> learn-packer.amazon-ebs.ubuntu: Connected to SSH!
==> learn-packer.amazon-ebs.ubuntu: Stopping the source instance...
    learn-packer.amazon-ebs.ubuntu: Stopping instance
==> learn-packer.amazon-ebs.ubuntu: Waiting for the instance to stop...
==> learn-packer.amazon-ebs.ubuntu: Creating AMI learn-packer-linux-aws-from-jeff from instance i-0ca3d8db7ad97eebe
    learn-packer.amazon-ebs.ubuntu: AMI: ami-0c076c5e9e4ea7173
==> learn-packer.amazon-ebs.ubuntu: Waiting for AMI to become ready...
==> learn-packer.amazon-ebs.ubuntu: Skipping Enable AMI deprecation...
==> learn-packer.amazon-ebs.ubuntu: Terminating the source AWS instance...
==> learn-packer.amazon-ebs.ubuntu: Cleaning up any extra volumes...
==> learn-packer.amazon-ebs.ubuntu: No volumes to clean up, skipping
==> learn-packer.amazon-ebs.ubuntu: Deleting temporary security group...
==> learn-packer.amazon-ebs.ubuntu: Deleting temporary keypair...
Build 'learn-packer.amazon-ebs.ubuntu' finished after 3 minutes 11 seconds.

==> Wait completed after 3 minutes 11 seconds

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

Verify

AMI 빌드가 완료되면 생성된 AMI ID를 확인할 수 있습니다. 이제 생성된 AMI를 사용하여 EC2 인스턴스를 시작할 수 있습니다. Packer와 Ansible을 사용한 이 과정은 자동화된 인프라 구축과 관리에 유용합니다.