본문 바로가기

퍼블릭 클라우드

Packer를 사용하여 AWS AMI(Amazon Machine Image)를 빌드하는 방법

728x90

Packer를 사용하여 AWS AMI(Amazon Machine Image)를 빌드하는 방법

Packer는 인프라를 코드로 정의하고 AMI와 같은 이미지를 생성하는 오픈 소스 도구입니다.

1. Packer 설치

Packer를 설치합니다. Packer의 공식 웹사이트(https://www.packer.io/)에서 다운로드하거나, 패키지 관리자를 통해 설치할 수 있습니다.

2. Packer 템플릿 작성

Packer는 JSON 형식의 템플릿을 사용하여 이미지 빌드를 정의합니다. Packer 템플릿은 다음과 같은 구성 요소를 포함합니다.

  • 빌드하는 베이스 이미지(소스 AMI)
  • 프로비저닝 (스크립트, 쉘 명령 등)
  • 이미지 생성 설정 (인스턴스 유형, 리전, 태그 등)

아래는 Packer 템플릿의 예시입니다.

{
  "variables": {
    "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
    "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "region": "us-west-2",
      "source_ami": "ami-0123456789abcdef0",
      "instance_type": "t2.micro",
      "ssh_username": "ec2-user",
      "ami_name": "my-ami-{{timestamp}}"
    }
  ]
}

3. Packer 템플릿 실행

터미널에서 Packer 템플릿을 실행하여 AMI 빌드를 시작합니다. 여기서 template.json은 작성한 Packer 템플릿 파일의 경로입니다.

packer build template.json

4. AMI 빌드 확인

Packer는 AMI를 생성하는 동안 지정한 설정대로 인스턴스를 시작하고 프로비저닝합니다. AMI 빌드가 완료되면 생성된 AMI의 ID가 출력됩니다.

위의 단계를 따라 Packer를 사용하여 AWS AMI를 빌드할 수 있습니다.

728x90
  • packer 파일 작성
vim aws-ubuntu.pkr.hc
packer {
  required_plugins {
    amazon = {
      version = ">= 1.1.1"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

################################################################################
################################################################################
################################################################################
variables {
  aws_profile      = "terraform"
  aws_region       = "ap-northeast-2" #{ 서울:ap-northeast-2, 도쿄:ap-northeast-1, 싱가포르:ap-southeast-1, 버지니아:us-east-1, 오리건:us-west-2 }
  ami_name         = "ubuntu18" #amazon2 | ubuntu22 | ubuntu18
  source_name      = "ubuntu18" #amazon2 | ubuntu22 | ubuntu18
  ami_version      = "0.1"
  instance_type    = "t3.small"
  project_name     = "web project"
  owner_name       = "pkradmin"
  environment_name = "development" #development | testing | staging | production 
  description      = "Managed by Packer"

}

################################################################################
################################################################################
################################################################################
locals {
  #   timestamp = regex_replace(timestamp(), "[- TZ:]", "")
  timestamp   = formatdate("YYMMDDhhmm", timestamp())
  ami_name    = var.ami_name
  ami_version = var.ami_version
  common_tags = {
    Name        = "${local.ami_name}-${local.ami_version}_${local.timestamp}"
    Project     = var.project_name
    Owner       = var.owner_name
    Environment = var.environment_name
    Packer      = true
    Description = var.description
  }
}

################################################################################
################################################################################
################################################################################
##### amazon(official accounts : 137112412989)
source "amazon-ebs" "amazon2" {
  profile                     = var.aws_profile
  region                      = var.aws_region
  ami_name                    = "${local.ami_name}-${local.ami_version}_${local.timestamp}"
  instance_type               = var.instance_type
  ssh_username                = "ec2-user"
  associate_public_ip_address = true

  source_ami_filter {
    filters = {
      name                = "amzn2-ami-hvm-2.0.*-x86_64-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["137112412989"]
  }

  tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )

  run_tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )

  snapshot_tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )
}

#### ubuntu(official accounts : 099720109477)
source "amazon-ebs" "ubuntu22" {
  profile                     = var.aws_profile
  region                      = var.aws_region
  ami_name                    = "${local.ami_name}-${local.ami_version}_${local.timestamp}"
  instance_type               = var.instance_type
  ssh_username                = "ubuntu"
  associate_public_ip_address = true

  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"]
  }

  tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )

  run_tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )

  snapshot_tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )
}

#### ubuntu(official accounts : 099720109477)
source "amazon-ebs" "ubuntu18" {
  profile                     = var.aws_profile
  region                      = var.aws_region
  ami_name                    = "${local.ami_name}-${local.ami_version}_${local.timestamp}"
  instance_type               = var.instance_type
  ssh_username                = "ubuntu"
  associate_public_ip_address = true

  source_ami_filter {
    filters = {
      name                = "ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"]
  }

  tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )

  run_tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )

  snapshot_tags = merge(
    local.common_tags,
    {
      Description = var.description
    }
  )
}

##### centos(official accounts : 125523088429)

################################################################################
################################################################################
################################################################################
build {
  name = "${local.ami_name}-${local.ami_version}_${local.timestamp}"
  sources = [
    "source.amazon-ebs.${var.source_name}"
  ]

  provisioner "shell" {
    environment_vars = [
      "FOO=hello world",
    ]
    script       = "provisioning-scripts/z.sh"
    pause_before = "10s"
    timeout      = "10s"
  }

  provisioner "shell" {
    inline = [
      "sleep 30",
      "echo \"FOO is $FOO\" > example.txt",
    ]
  }
}
  • z.sh 스크립트 파일 작성
mkdir provisioning-scripts
vim provisioning-scripts/z.sh
#!/bin/bash

sleep 30

echo "script execute"

echo \"FOO is $FOO\" > example.txt
packer init .
packer fmt .
packer validate .
$ packer validate .
The configuration is valid.
packer build .
$ packer build .
ubuntu-0.1_2208301441.amazon-ebs.ubuntu: output will be in this color.

==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Prevalidating AMI Name: ubuntu-0.1_2208301441
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Found Image ID: ami-08f869ae259b6bc98
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Creating temporary keypair: packer_630e2186-36cd-9da6-6e53-61836da7eb7e
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_630e2188-d048-4500-66f7-14ba550c80ab
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Launching a source AWS instance...
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Packer": "true"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Project": "project_name"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Description": "Managed by Packer"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Environment": "environment_name"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Name": "ubuntu-0.1_2208301441"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Owner": "owner_name"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Instance ID: i-0a70b7e2d59d93116
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Waiting for instance (i-0a70b7e2d59d93116) to become ready...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Using SSH communicator to connect: 3.35.71.219
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Waiting for SSH to become available...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Connected to SSH!
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Pausing 10s before the next provisioner...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Provisioning with shell script: provisioning-scripts/z.sh
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: script execute
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Provisioning with shell script: /var/folders/56/1ltpc_xj6wb35k7pfvv9h0340000gn/T/packer-shell257669287
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: This provisioner runs last
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Stopping the source instance...
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Stopping instance
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Waiting for the instance to stop...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Creating AMI ubuntu-0.1_2208301441 from instance i-0a70b7e2d59d93116
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: AMI: ami-0496287d45333c2dd
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Waiting for AMI to become ready...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Skipping Enable AMI deprecation...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tags to AMI (ami-0496287d45333c2dd)...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Tagging snapshot: snap-0f83f54246394e406
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Creating AMI tags
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Description": "Managed by Packer"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Environment": "environment_name"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Name": "ubuntu-0.1_2208301441"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Owner": "owner_name"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Packer": "true"
    ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Adding tag: "Project": "project_name"
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Creating snapshot tags
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Terminating the source AWS instance...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Cleaning up any extra volumes...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: No volumes to clean up, skipping
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Deleting temporary security group...
==> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: Deleting temporary keypair...
Build 'ubuntu-0.1_2208301441.amazon-ebs.ubuntu' finished after 3 minutes 55 seconds.

==> Wait completed after 3 minutes 55 seconds

==> Builds finished. The artifacts of successful builds are:
--> ubuntu-0.1_2208301441.amazon-ebs.ubuntu: AMIs were created:
ap-northeast-2: ami-0496287d45333c2dd
  • AWS Management Console > EC2 > 이미지 > AMI

a1

 

참고URL

- packer 설치 : https://sangchul.kr/394

https://learn.hashicorp.com/tutorials/packer/get-started-install-cli

 

728x90