Packer 와 Ansible을 이용한 node.js VM 이미지 생성하기
Packer와 Ansible을 이용하여, node.js 이미지 생성하기
조대협 (http://bcho.tistory.com)
앞서 글에서 패커를 이용한 이미지 생성 및, 이미지 타입(http://bcho.tistory.com/1226) 에 대해서 알아보았다. 이번 글에서는 node.js 가 깔려있는 파운데이션 타입의 구글 클라우드 VM이미지를 패커와 앤서블을 이용해서 구현해 보도록 한다. 이 글을 이해하기 위해서는 http://bcho.tistory.com/1225 에 대한 이해가 필요하다.
구성은 다음과 같다. 패커를 이용하여, Debian OS 기반의 이미지를 만든 후에, 패커의 Provisioner를 이용하여 Ansible을 설치하고, 이 설치된 Ansible을 이용하여 node.js등을 설치하는 playbook 을 실행하는 순서로 node.js용 이미지를 만든다.
패커 스크립트는 다음과 같다.
builder 부분은 예전과 같다.(http://bcho.tistory.com/1225) Debian 이미지를 기반으로 VM을 생성한다.
VM 생성후에, 소프트웨어 설치등을 정의하는 부분은 provisioner 라는 부분에 정의되는데, 두 타입의 Provisioner가 사용되었다. 첫번째는 shell 타입이고 두번째는 ansible-local 형태의 provisioner이다.
{
"variables":{
"project_id":"terrycho-sandbox",
"prefix":"debian-9-nodejs"
},
"builders":[
{
"type":"googlecompute",
"account_file":"/Users/terrycho/keys/terrycho-sandbox-projectowner.json",
"project_id":"{{user `project_id`}}",
"source_image":"debian-9-stretch-v20180105",
"zone":"us-central1-a",
"ssh_username":"ubuntu",
"image_name":"{{user `prefix`}}-{{timestamp}}",
"machine_type":"n1-standard-4"
}
],
"provisioners":[
{
"type":"shell",
"execute_command":"echo 'install ansible' | {{ .Vars }} sudo -E -S sh '{{ .Path }}'",
"inline":[
"sleep 30",
"apt-add-repository ppa:rquillo/ansible",
"/usr/bin/apt-get update",
"/usr/bin/apt-get -y install ansible"
]
},
{
"type":"ansible-local",
"playbook_file":"./nodejs_playbook.yml"
}
]
}
첫번째 provisioner에서는 ansible을 apt-get으로 설치하기 위해서 sudo 권한으로 apt-get update를 실행하여, 리파지토리 정보를 업데이트 한후에, apt-get -y install ansible을 이용하여, ansible을 설치한다.
두번째 provisioner는 ansible-local provisioner로, 앞단계에서 설치된 ansible을 로컬에서 실행하여, playbook을 실행해주는 코드이다.
ansible은 Configuration management & Deployment 도구로, 나중에 기회가 되면 다른글을 이용해서 소개하도록 한다.
이 코드에서 호출된 nodejs_playbook.yml 파일의 내용은 다음과 같다.
- hosts: all
tasks:
- name : create user node
become : true
user :
name: nodejs
state : present
- name : update apt-get install
shell : curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
- name : install node.js LTS
become : true
#become_user: nodejs
apt : pkg=nodejs state=installed update_cache=true
hosts:all로, ansible에 등록된 모든 호스트에 대해서 스크립트를 실행하도록 한다. 여기서는 별도의 호스트를 등록하지 않았고, ansible-local 타입으로 실행하였기 때문에, 이 호스트 (localhost)에만 스크립트가 실행된다.
크게 3단계로 실행이 되는데, 첫번째가 nodejs라는 사용자를 만드는 단계로, user 라는 모듈을 사용하여 nodejs라는 사용자를 생성하였다. 이 사용자 계정은 향후 애플리케이션이 배포되었을때, nodejs를 실행할 계정으로 사용된다. 사용자 계정을 만들기 위해서는 root 계정을 획득해야하기 때문에, become: true로 하여 sudo 로 명령을 실행하도록 하였다.
두번째는 node.js를 인스톨하기 위해서 설치전 사전 스크립트를 실행하는 부분이다. apt-get install을 디폴트 상태에서 실행하게 되면 node.js 4.x 버전이 인스톨된다. 최신 8.X 버전을 인스톨하기 위해서, 스크립트를 실행한다. 앤서블 모듈중에서 shell 모듈을 이용하여 쉘 명령어를 실행하였다.
세번째 마지막은 apt 모듈을 이용하여, node.js를 인스톨하도록 한다.
스크립트 작업이 끝났으면, 이미지를 생성해보자
%packer build node.json
으로 실행을 하면 이미지가 생성된다. 생성된 이미지는 구글 클라우드 콘솔의 GCE (Google Compute Engine)의 Images 메뉴에서 확인이 가능하다.
다음과 같이 debian-9-nodejs-*로 새로운 이미지가 생성된것을 확인할 수 있다.
생성된 이미지가 제대로 되었는지를 확인하기 위해서, 이 이미지로 VM을 생성해서 nodejs 버전을 확인해보면 다음과 같이 8.9.4 가 인스톨 되었음을 확인할 수 있다.
또한 nodejs로 된 계정이 생성되었는지를 확인하기 위해서 /etc/passwd 내에 사용자 정보가 생성되었는지를 확인해보면 아래와 같이 nodejs 이름으로 계정이 생성되었음을 확인할 수 있다.
참고 : https://blog.codeship.com/packer-ansible/