[패커] packer를 사용해서 프로비저닝 된 인스턴스 구축하기

문제상황

프라이빗 서브넷을 사용한 인스턴스에서 nginx aws cli 등등 패키지를 다운받아야 하는 상황인데 NAT가 안 붙어있는데 어떻게 해결해야할 것인가?

시행착오

처음에는 ec2 인스턴스를 만들 때 Userdata에 스크립트를 넣어서 인스턴스를 만들면 될 줄 알았는데, 이것또한 NAT가 없으니 프로비저닝이 되지 않았습니다. 

해결방법

packer를 사용해서 프로비저닝 된 AMI를 만들어서 해결합니다!


MAC Packer 설치 가이드 

brew install hashicorp/tap/packer

packer를 hashicorp/tap/packer를 사용해서 설치합니다.  

 

packer

설치 되었는지는, packer 명령으로 확인할 수 있어요!


이제 제가 만들어볼까요!

디렉토리 구조입니다.


install-aws-cli.sh

이 스크립트 파일은 우분투 환경에서 AWS Cli설치, Credential 설정, 그리고 nginx설치와 config파일 입력까지 포함합니다. 

#!/bin/bash

# AWS CLI 설치
sudo apt-get update -y
sudo apt-get install -y nginx python3-pip

# Install AWS CLI using pip
sudo pip3 install awscli

# AWS Credential 설정
mkdir -p /home/ubuntu/.aws
cat > /home/ubuntu/.aws/credentials <<EOL
[default]
aws_access_key_id = ${AWS_ACCESS_KEY}
aws_secret_access_key = ${AWS_SECRET_KEY}
EOL

cat > /home/ubuntu/.aws/config <<EOL
[default]
region = ${AWS_REGION}
EOL

# 설정 파일의 소유권 변경
sudo chown -R ubuntu:ubuntu /home/ubuntu/.aws

echo "AWS_ACCESS_KEY: $AWS_ACCESS_KEY"
echo "AWS_SECRET_KEY: $AWS_SECRET_KEY"
echo "AWS_REGION: $AWS_REGION"

# Configure nginx
sudo bash -c "cat > /etc/nginx/nginx.conf" <<'EOL'
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    #ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    #ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    #include /etc/nginx/sites-enabled/*;

    ##
    # Server Configs
    ##

    server {
        listen 80;
        server_name office.onthelook.internal;

        ##
        # Location Configs
        ##
         location / {
} 
        location /<엔드포인트1> {
            alias /home/ubuntu/<경로>;
            index index.html;
        }

        location /<엔드포인트2> {
            alias /home/ubuntu/<파일경로>/build;
            index index.html;
        }

        ##
        # Error Pages Configs
        ##

        error_page 404 /404.html;
        location = /404.html {
            internal;
        }

        ##
        # Redirects Configs
        ##


        # Redirect non-www to www
        if ($host !~* ^(www)) {
            rewrite ^(.*)$ http://www.$host$1 permanent;
        }

        # Redirect HTTP to HTTPS
        #if ($scheme != "https") {
        #    return 301 https://$server_name$request_uri;
        #}

        ##
        # SSL Configs
        ##

        #ssl_certificate /etc/ssl/certs/your_cert.crt;
        #ssl_certificate_key /etc/ssl/private/your_key.key;
        #ssl_session_timeout 5m;
        #ssl_protocols TLSv1.1 TLSv1.2;
        #ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        #ssl_prefer_server_ciphers on;
}
}

EOL

# Start and enable nginx
sudo systemctl start nginx
sudo systemctl enable nginx

aws-ubuntu.pkr.hcl

이 hcl 파일은 우분투 20.04 이미지를 기반으로 만들고, scripts 디렉토리안에있는 install-aws-cli.sh를 이용하여 프로비저닝합니다. 

AWS credential 에 들어갈 내용들을 환경변수로 선언해주었습니다.

packer {
  required_plugins {
    amazon = {
      version = ">= 0.0.1"
      source  = "github.com/hashicorp/amazon"
    }
  }
}
 
source "amazon-ebs" "ubuntu" {
  ami_name      = "${var.ami_prefix}-${local.timestamp}"
  instance_type = "t2.micro"
  region        = "ap-northeast-2"
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"]
  }
  ssh_username = "ubuntu"
}
 
build {
  sources = [
    "source.amazon-ebs.ubuntu"
  ]
 
  provisioner "shell" {
   script          = "scripts/install-aws-cli.sh"
   environment_vars = [
    "AWS_ACCESS_KEY=${var.aws_access_key}",
    "AWS_SECRET_KEY=${var.aws_secret_key}",
    "AWS_REGION=${var.aws_region}"
  ]
}
}

variable "ami_prefix" {
  type    = string
  default = "private-backoffice-correct-ami"
}

locals {
  timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}

 


variables.pkr.hcl

변수에 대해서 값을 넣어줍니다. variable에 값에서 default를 비워주겠습니다. 

variable "aws_access_key" {
  type    = string
  default = ""
}

variable "aws_secret_key" {
  type    = string
  default = ""
}

variable "aws_region" {
  type    = string
  default = ""
}

variables.auto.pkvars.hcl

variables.auto.pkvars.hcl에서 디폴트에 들어갈  값들을 넣어주면 packer bulid를 할 때 그 값들이 적용되어서 들어가게됩니다.

aws_access_key = "AXXXXXXXXXXXXX"
aws_secret_key = "XXXXXXXXXXXaXXXXXXXXX"
aws_region     = "ap-northeast-2"

VScode SSH 연결 config

Host private-backoffice-fixed
	HostName <프라이빗 서브넷>
	User ubuntu
	IdentityFile /<pem키 경로>
	ProxyCommand ssh -W %h:%p backoffice-bastion

이 부분은 따로 다른 페이지에서 정리해놓겠습니다.


그 후 이렇게 만들어진 프라이빗 인스턴스 안에서

aws configure list

명령을 하게 되면, variables.auto.pkvars.hcl에 넣었던 내용들이 잘 들어가서 프로비저닝되었음을 확인할 수 있다. 

뿐만아니라 aws 명령어가 입력이 되는것을 확인하여서 쉘 스크립트로 userdata에 넣었던 내용들(aws 명령어)도 잘 프로비저닝되어서 들어간 것을 확인할 수 있습니다! 

 

variables.pkr.hcl 에서 default에 값을 넣어서 프로비저닝을 할 수도 있지만,  variables.auto.pkvars.hcl에 값을 넣고 사용하면서 깃이나 어딘가에 코드를 공유할 때 커밋 안하면 되니까 재사용성도 높은것같아서 packer 잘 사용하게 될 것 같습니다!

JUNE .

20'S LIFE IN SYDNEY and BUSAN

    이미지 맵

    DevOps Study/Packer 다른 글

    이전 글

    다음 글