본문 바로가기

AWS

[Packer] Packer를 이용한 EC2 AMI 생성

반응형

Packer의 정의는 쉽게 VM의 Image를 생성해주는 Image Builder라고 생각하면 된다.

 

Packer 설치

Packer는 yum, apt-get, choco 등 여러가지 방식으로 설치할 수 있지만 아래의 설치 방법은 wget을 이용하여 zip 파일을 다운로드 받은 후 설치한 방식이다.

export PACKER_RELEASE="1.7.4"

sudo cd /tmp/

wget https://releases.hashicorp.com/packer/${PACKER_RELEASE}/packer_${PACKER_RELEASE}_linux_amd64.zip

sudo unzip packer_${PACKER_RELEASE}_linux_amd64.zip

sudo mv packer /usr/local/bin

packer --version

 

Packer Workflow

Packer는 이미지를 만들어주는, Image Builder이다. 즉, VM의 상태값을 만들어준다.

이를 위해서는 '어느 Source Image로부터 어떠한 작업들을 할 것이다.'라는 명세서가 필요하게 된다. 이것이 아래의 그림에서는 packer.json이 되겠다.

아래는 1) Build, 2) Provision, 3) Post-Process 3 단계를 거치는 것으로 보인다. Build와 Provision은 이미지를 빌드하고 배포해주는 작업이며, Post-Process는 2개의 작업을 완료한 이후에 어떤 마무리 작업을 할 것인지 정할 수 있다.

⇒ 아마도 AMI가 정상적으로 만들어졌는지 TEST를 할 수 있을 것으로 보인다.

Before Start packer

패커를 사용하기 전에 간단히 큰 틀을 알아보자.

참고로, 모든 내용은 Packer Docs를 보는 것이 제일 빠르다.

HCLjson 2가지 타입을 모두 설명하고 있다.

https://www.packer.io/docs/builders/amazon

https://www.packer.io/docs/builders/amazon/ebs

패커로 EC2 AMI를 생성하기 위해서는 아래의 정보들이 필요하다.

  1. AWS 계정에 접근하기 위한 자격 증명
  2. Source AMI에 대한 정보
  3. EC2 접근 방식
  4. Provision

필자는 AWS 계정에 접근하기 위한 자격 증명으로 ~/.aws/credentials 파일에 Access Key, Secret Key를 저장하여 사용하였다. 이 외에 하드 코딩으로 Access Key, Secret Key를 사용할 수도 있고 Assume Role 등 또한 사용할 수 있을 것으로 보인다.

이렇게 인증 후 EC2에 대한 권한(인가)까지 부여된 자격 증명 정보를 이용해 AWS EC2 내의 서비스 (EC2 생성 및 종료, 이미지 생섯 ..) API에 Action을 수행할 수 있게 된다.

 

>> 아래는 Packer가 EC2 AMI를 Build하기 위한 최소 Policy임

(스팟 인스턴스 등을 생성하기 위해서는 추가 권한이 필요하며 Docs를 참고할 것)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:AttachVolume",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:CopyImage",
        "ec2:CreateImage",
        "ec2:CreateKeypair",
        "ec2:CreateSecurityGroup",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "ec2:CreateVolume",
        "ec2:DeleteKeyPair",
        "ec2:DeleteSecurityGroup",
        "ec2:DeleteSnapshot",
        "ec2:DeleteVolume",
        "ec2:DeregisterImage",
        "ec2:DescribeImageAttribute",
        "ec2:DescribeImages",
        "ec2:DescribeInstances",
        "ec2:DescribeInstanceStatus",
        "ec2:DescribeRegions",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSnapshots",
        "ec2:DescribeSubnets",
        "ec2:DescribeTags",
        "ec2:DescribeVolumes",
        "ec2:DetachVolume",
        "ec2:GetPasswordData",
        "ec2:ModifyImageAttribute",
        "ec2:ModifyInstanceAttribute",
        "ec2:ModifySnapshotAttribute",
        "ec2:RegisterImage",
        "ec2:RunInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances"
      ],
      "Resource": "*"
    }
  ]
}

 

 

그 이후, Packer는 템플릿에 명시된 대로 작업을 수행하게 된다.

Ex)

# file: example.pkr.hcl

# Terraform을 접해본 사람들은 쉽게 이해할 수 있을 것인데
# filter를 걸어서 어떤 AMI를 가져올 것인지,
# 누구의 AMI를 가져오고, Region은 어디이며 가장 최근 것을 가져오겠다는 것을 정의

data "amazon-ami" "example" {
  filters = {
    virtualization-type = "hvm"
    name                = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
    root-device-type    = "ebs"
  }
  owners      = ["099720109477"]
  most_recent = true
  region      = "us-east-1"
}

# 생성될 AMI Name은 어떻게 생성할 것이며, 
# 인스턴스의 Type, Region, 원본 AMI, 
# ssh에 접속할 user 이름, 
# ssh의 인터페이스 (여기에서는 session_manager)
# 통신 방식 : SSH
# 등을 지정할 수 있다.
source "amazon-ebs" "ssm-example" {
  ami_name             = "packer_AWS {{timestamp}}"
  instance_type        = "t2.micro"
  region               = "us-east-1"
  source_ami           = data.amazon-ami.example.id
  ssh_username         = "ubuntu"
  ssh_interface        = "session_manager"
  communicator         = "ssh"
  iam_instance_profile = "myinstanceprofile"
}

# 위에서 source AMI로부터 shell로 프로비저닝을 하게 된다.
# inline으로도 할 수 있고, script를 지정할 수도 있다. 보통은 script를 많이 하는 것으로
# 추정된다.
build {
  sources = ["source.amazon-ebs.ssm-example"]

  provisioner "shell" {
    inline = ["echo Connected via SSM at '${build.User}@${build.Host}:${build.Port}'"]
  }
}

 

Packer Files

보통 Internet에서는 Packer.json처럼 json 형식으로 템플릿을 만드는 경우가 많다. 하지만 Pakcer는 하시코프에서 만든 오픈소스 툴인 만큼 hcl 형식으로도 템플릿을 만들 수 있다.

⇒ Terraform에 익숙한 유저라면 hcl이 좀 더 편할 것이고, 개발자들이라면 json 형식이 좀 더 편할 것으로 생각된다.

  • packer.pkrvars.hcm : 패커 템플릿에서 사용할 변수들을 모아두었다.
  • tomcat_ami.prk.hcl : 패커 템플릿
  • tomcat_install.sh : 패커의 Provision 부분에서 작동할 쉘 스크립트 파일

Template File

1. tomcat_ami.pkr.hcl

source "amazon-ebs" "ec2_ami" {
    profile = var.profile
    region = var.region
    ami_name = "${var.env}-WAS-AMI-${var.version}"
    instance_type = var.instance_type
    source_ami_filter {
        filters = {
            virtualization-type = "hvm"
            name                = "amzn2-ami-ecs-hvm-2*"
            root-device-type    = "ebs"
            architecture        = "x86_64"
        }
        owners                = ["amazon"]
        most_recent           = true
    }

    # Network Configuration
    subnet_id = var.subnet_id
    ssh_timeout = "10m"

    # Temporarily connect to EC2 using ssh protocol,
    # ssh ec2-user@{{public_ip}}
    communicator              = "ssh"
    ssh_username              = "ec2-user"
}

build {
    # Get EC2 Image
    sources = [
        "source.amazon-ebs.ec2_ami"
    ]

    # Provisioner
    provisioner "shell" {
        script = "tomcat_install.sh"
    }
}

# Variable Settings
variable "profile" {
    default = ""
}

variable "region" {
    default = ""
}

variable "env" {
    default = ""
}

variable "instance_type" {
    default = ""
}

variable "subnet_id" {
    default = ""
}

variable "version" {
    default = ""
}

 

2. packer.pkrvars.hcl

profile = "default"  # name of aws cli profile
region = "ap-northeast-2"  # your selected aws region
env = "test"
instance_type = "t2.micro"
subnet_id = "subnet-xxxxxxxx"
version = "v0.1"

 

Packer Validate

패커 코드에 문제가 있는지 확인해주는 명령어

packer validate -var-file=packer.pkrvars.hcl tomcat_ami.pkr.hcl

 

Packer Build

본격적으로 패커 이미지를 빌드해주는 명령어

packer build -var-file={{variable_file}} {{TEMPLATE}}

Packer란 놈이 임시 인스턴스 (Packer Builder)를 생성하여 본인이 알아서 지지고 볶는다.

이미지를 성공적으로 생성한 이후에는 알아서 AMI 생성 및 Shutdown 모두 하고 결과까지 알려준다.

 

이미지 생성 완료

 

EC2 Public IP로 접속한 모습

따로 EC2 Instance에 접속하지 않아도 기 생성한 AMI 이미지로 Instance를 만들었더니 Tomcat 서비스가 잘 올라온 EC2를 확인할 수 있다.

 

Packer 정리

Packer는 말 그대로 AMI를 생성해준다. AWS에서는 Image Builder이 Pakcer와 유사한 기능을 하고 있다.

Pakcer는 단독으로 사용하는 것이 아니라 Ansible, Spinnaker 등의 CD Tool, Configuration Management Tool들과 같이 사용되며 알아두면 여러모로 좋다.

 

반응형