Skip to content

Latest commit

 

History

History
491 lines (404 loc) · 14.1 KB

README.md

File metadata and controls

491 lines (404 loc) · 14.1 KB

준비하기

네트워크 준비하기

Cloud Formation Template을 이용해 네트워크(VPC) 준비하기
VPC 구성은 Public Subnet 2개 / Private Subnet 2개 / NAT Gateway 1개(비용 발생) 로 구성됩니다.
테스트할 VPC 가 있는 분은 따로 진행하지 않으셔도 됩니다.

EC2 생성하기

초기에 EC2는 2대 생성 합니다.
1대는 ansible playbook을 작성하고 관리하는 ansible-server.
다른 1대는 ansible playbook을 이용해 provisioning 할 목적의 target-server.

  1. AWS Console 접속
  2. 서울 리전(ap-northeast-2)으로 이동
  3. AWS EC2 Console 로 이동
  4. EC2 생성하기 - Amazon Linux AMI 2018.03.0 으로 생성
  5. EC2 Type - t2.micro 로 선택
  6. 기 생성된 VPC 중 Public Subnet 에 위치하도록 선택
  7. Auto-assign Public IP 옵션 True
  8. Security Group 에 22번 포트 접속 가능하도록 설정
  9. Keypair 생성 후 다운로드 - 편의를 위해 2대 모두 같은 keypair로 선택.
  10. EC2 생성 완료

EC2 접속하기

Mac / Linux
## {중괄호 부분은 여러분이 생성한 Key pair, EC2 IP에 맞게 변경하세요}
$ ssh -i {YOUR_KEY_PAIR.pem} ec2-user@{10.100.0.0}

# 예시
$ ssh -i aws-krug-handson.pem [email protected]
Windows
  1. Putty 다운로드
    https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
  2. PuTTYgen을 이용하여 pem 키를 ppk (putty private key)로 변경하기
    https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/putty.html#putty-private-key
  3. Putty 를 이용해 ec2 에 접속하기
    https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/putty.html#putty-ssh

Ansible 설치 및 사용하기

Ansible 공식 설치 메뉴얼은 https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html 에서 확인 가능
apt-get, yum, pip, brew 등 다양한 방법으로 설치가 가능함.

Python pip을 이용한 Ansible 설치하기
## sudo 권한 필요
$ sudo pip install ansible

## 설치 확인
$ ansible --version

$ which ansible
# /usr/local/bin/ansible

Ansible 을 이용해 명령어 실행 해보기

Ad-hoc Command 에 대하여 알아보기
https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html

  • Ansible이 강력한 이유는 Playbook을 사용하기 때문
  • ad-hoc 명령어는 한번 명령어를 사용하고 버려도 되는 경우에 사용함 (거의 쓸일이 없기는 함)
# ansible HOST -m MODULE_NAME
$ ansible localhost -m ping

Playbook 구조 만들기

Playbook 디렉토리를 생성하고 각 Role별 Tasks, Templates, files 등 디렉토리 구조를 만든다.

## Ansible Playbook 을 관리할 디렉토리로 이동.
$ cd {your directory}

$ mkdir -p playbook/roles/httpd/
$ cd playbook/roles/httpd/
$ mkdir files handlers defaults templates tasks
$ cd -
$ tree
.
└── playbook
    └── roles
        └── httpd
            ├── defaults
            ├── files
            ├── handlers
            ├── tasks
            └── templates

Step 1 - ansible 기본 config

ansible 을 수행할 directory에 ansible.cfg 파일을 생성한다.

[defaults]
host_key_checking = False
become_user = root
remote_user = ec2-user
timeout = 60000
callback_whitelist = profile_tasks
private_key_file = ~/.ssh/ansible-packer.pem
inventory = ./my-inventory

[ssh_connection]
pipelining = True

서버에 접속할 인증키를 ~/.ssh/ansible-packer.pem 에 위치한다.

ansible을 수행할 directory에 my-inventory 파일을 생성한다.

[target]
13.209.82.234

Step 2 - Apache 기본 설치 / 루프 사용하기

$ vim playbook/roles/httpd/tasks/main.yml
---
- name: install httpd with yum
  yum: name={{ item.package }}
  loop:
  - { package: httpd }
  - { package: mod_ssl }
# ansible-playbook --connection=local -i "127.0.0.1," playbook/httpd.yml
$ ansible-playbook -l target playbook/httpd.yml

Step 3 - 변수 적용

playbook/roles/httpd/defaults/main.yml 에 변수 선언
---
service: awskrug
playbook/roles/httpd/tasks/main.yml 에 스크립트 추가
### 기존 작성 생략

### {{ 변수명 }} 으로 변수 처리
- name: create apache document root directory
  file:
    path: "/data/apache/{{ service }}/docroot"
    state: directory
    owner: apache
    group: apache
    mode: 0755
    recurse: yes
# Ansible Playbook 실행해보기
$ ansible-playbook -l target playbook/httpd.yml

Step 4 - Templates 적용하기

playbook/roles/httpd/defaults/main.yml 에 변수 추가
---
service: awskrug
http_port: 10180
playbook/roles/httpd/templates/http-awskrug-vhost.conf.j2 에 변수 추가
<VirtualHost *:{{ http_port }}>

  DocumentRoot /data/apache/{{ service }}/docroot

  ErrorLog     /log/apache/{{ service }}/{{ service }}.error_log
  CustomLog    /log/apache/{{ service }}/{{ service }}.access_log common

</VirtualHost>
playbook/roles/httpd/tasks/main.yml 에 templates / lineinfile 모듈 명령어 추가
### 기존 작성 생략

### template을 이용해 변수 적용
- name: copy apache virtual host configuration
  template:
    src: "http-{{ service }}-vhost.conf.j2"
    dest: "/etc/httpd/conf.d/http-{{ service }}-vhost.conf"
    owner: apache
    group: apache
    mode: 0644

### lineinfile 을 이용해 파일 내 특정 라인만 내용 변경
- name: change apache default listening port configuration
  lineinfile:
    dest: /etc/httpd/conf/httpd.conf
    regexp: "^Listen"
    line: "Listen {{ http_port }}"
# Ansible Playbook 실행해보기
$ ansible-playbook -l target playbook/httpd.yml
cli 명령 파라미터로 변수 override 해보기
# Ansible Playbook 실행해보기
### -e http_port=20080 옵션 추가
$ ansible-playbook -l target playbook/httpd.yml -e http_port=20080

Step 5 - Handlers 를 이용해 apache 재시작 하기

playbook/roles/httpd/handlers/main.yml 에 handler script 작성
---
- name: restart apache webserver
  service:
    name: httpd
    state: restarted
playbook/roles/httpd/tasks/main.yml 에 notify 모듈 명령어 추가
### 기존 아래 이름의 Task에 notify 추가
- name: copy apache virtual host configuration
  template:
    src: "http-{{ service }}-vhost.conf.j2"
    dest: /etc/httpd/conf.d/http-vhost.conf
    owner: apache
    group: apache
    mode: 0644
  notify:
    - restart apache webserver
# Ansible Playbook 실행해보기
$ ansible-playbook -l target playbook/httpd.yml

PLAY [all] ***************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [127.0.0.1]

TASK [httpd : install httpd] *********************************************************
ok: [127.0.0.1] => (item={u'package': u'httpd'})
ok: [127.0.0.1] => (item={u'package': u'mod_ssl'})

TASK [httpd : create apache document root directory] *********************************
ok: [127.0.0.1]

## TASK에 변경(changed)이 있으면,..
TASK [httpd : copy apache virtual host configuration] ********************************
changed: [127.0.0.1]

## HANDLER가 수행됨.
RUNNING HANDLER [httpd : restart apache webserver] ***********************************
changed: [127.0.0.1]

PLAY RECAP ***************************************************************************
127.0.0.1                  : ok=5    changed=1    unreachable=0    failed=0

Step 6 - Handlers에 대해 좀 더 이해하기

notify 코드 이후에 더 task 를 추가해 봅니다.

playbook/roles/httpd/tasks/main.yml 에 notify 모듈 명령어 추가
## 기존 코드 생략

- name: create apache log directory
  file:
    path: "/log/apache/{{ service }}/"
    state: directory
    owner: apache
    group: apache
    mode: 0755
    recurse: yes
# Ansible Playbook 실행해보기
$ ansible-playbook -l target playbook/httpd.yml

PLAY [all] ***************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [127.0.0.1]

TASK [httpd : install httpd] *********************************************************
ok: [127.0.0.1] => (item={u'package': u'httpd'})
ok: [127.0.0.1] => (item={u'package': u'mod_ssl'})

TASK [httpd : create apache document root directory] *********************************
ok: [127.0.0.1]

TASK [httpd : copy apache virtual host configuration] ********************************
changed: [127.0.0.1]

TASK [httpd : change apache default listening port configuration] ********************
ok: [127.0.0.1]

TASK [httpd : create apache log directory] *******************************************
ok: [127.0.0.1]

## Handler가 가장 마지막에 실행 됨
RUNNING HANDLER [httpd : restart apache webserver] ***********************************
changed: [127.0.0.1]

PLAY RECAP ***************************************************************************
127.0.0.1                  : ok=7    changed=2    unreachable=0    failed=0

notify에 등록된 handler는 바로 실행되지 않고, tasks 실행이 끝난 뒤 마지막에 수행 됨.
원하는 지점에서 실행하게 하려면 아래처럼 코드를 추가 해야 함.

### 기존 코드 notify 아래 - meta: flush_handlers 추가
- name: copy apache virtual host configuration
  template:
    src: "http-{{ service }}-vhost.conf.j2"
    dest: /etc/httpd/conf.d/http-vhost.conf
    owner: apache
    group: apache
    mode: 0644
  notify:
    - restart apache webserver

- meta: flush_handlers
# Ansible Playbook 실행해보기
$ ansible-playbook -l target playbook/httpd.yml

PLAY [all] ***************************************************************************

TASK [Gathering Facts] ***************************************************************
ok: [127.0.0.1]

TASK [httpd : install httpd] *********************************************************
ok: [127.0.0.1] => (item={u'package': u'httpd'})
ok: [127.0.0.1] => (item={u'package': u'mod_ssl'})

TASK [httpd : create apache document root directory] *********************************
ok: [127.0.0.1]

TASK [httpd : copy apache virtual host configuration] ********************************
changed: [127.0.0.1]

## flush 시점에 쌓여있던 handler trigger가 모두 수행됨.
RUNNING HANDLER [httpd : restart apache webserver] ***********************************
changed: [127.0.0.1]

TASK [httpd : change apache default listening port configuration] ********************
ok: [127.0.0.1]

TASK [httpd : create apache log directory] *******************************************
ok: [127.0.0.1]

PLAY RECAP ***************************************************************************
127.0.0.1                  : ok=7    changed=2    unreachable=0    failed=0

Packer 설치하기

Ansible 코드를 작성하여 packer를 설치해 봅니다.

role 추가하기

$ mkdir -p playbook/roles/packer/tasks/
playbook/roles/packer/tasks/main.yml
---
- name: download packer binary
  get_url:
    url: https://releases.hashicorp.com/packer/1.3.2/packer_1.3.2_linux_amd64.zip
    dest: /home/ec2-user/packer.zip
    mode: 0644

- name: unzip packer binary
  unarchive:
    src: /home/ec2-user/packer.zip
    dest: /usr/bin/
    remote_src: yes
    mode: 0755
  become: yes
  become_user: root
playbook/packer.yml
---
- hosts: all
  roles:
  - packer
실행하기
$ ansible-playbook -l target playbook/packer.yml

Packer template 작성하기

Template 작성

packer를 수행할 폴더에서 template file을 생성한다.

packer_hands_on/basic-template.json
{
  "builders": [{
    "type": "amazon-ebs",
    "subnet_id": "{{user `aws_subnet_id`}}",
    "vpc_id": "{{user `aws_vpc_id`}}",
    "region": "{{user `aws_region`}}",
    "security_group_id": "{{user `security_group_id`}}",
    "ssh_keypair_name": "ansible-packer",
    "ssh_username": "ec2-user",
    "ssh_private_key_file": "ansible-packer.pem",
    "ssh_pty": "false",
    "ssh_interface": "private_ip",
    "instance_type": "t2.micro",
    "source_ami": "{{user `aws_source_ami`}}",
    "ami_name": "{{user `aws_target_ami`}}",
    "associate_public_ip_address": "true",
    "tags": {"service": "{{user `service`}}"},
    "run_tags": {
        "Name": "{{user `ec2-name`}}",
        "Cost-Center": "awskrug"
    },
    "ami_block_device_mappings": [
      {
        "device_name": "/dev/sda1",
        "delete_on_termination": "true",
        "volume_type": "gp2"
      }
    ]
  }],
 "provisioners": [{
   "type": "ansible",
   "playbook_file": "/home/ec2-user/playbook/httpd.yml",
   "user": "ec2-user",
   "sftp_command": "/usr/libexec/openssh/sftp-server",
   "extra_arguments": [
     "--extra-vars",
     "service={{user `service`}}"
   ]
 }]
}

variable file 작성

template에 변수 처리 할 내용을 variable로 작성할 수 있습니다.
여기서 변수 값은 여러분들이 생성하신 vpc 및 subnet 등의 정보롤 대체하시면 됩니다.

packer_hands_on/var-file.json
{
  "aws_vpc_id": "vpc-c10536a9",
  "aws_subnet_id": "subnet-65a6910d",
  "security_group_id": "sg-0b26500a049ce59cb",
  "aws_source_ami": "ami-0a10b2721688ce9d2",
  "aws_target_ami": "my-first-ami",
  "service": "awskrug",
  "ec2-name": "now-baking"
}

packer 스크립트를 수행할 ec2에 권한 주기

packer 를 수행할 서버는 ec2 및 ami등 새로 생성할 수 있는 권한이 필요합니다.
AWS Console 에서 IAM으로 이동하여 ec2 role을 생성합니다.

IAM > Roles > Create Role 로 이동합니다.

  • EC2 가 사용할 Role로 지정 후 다음으로 넘어갑니다.
  • Attach permissions policies 에서 편의상 AmazonEC2FullAccess 를 선택하고 다음으로 넘어갑니다.
  • Tag 지정은 무시하고 넘어갑니다.
  • Role Name에는 packer-role 로 지정합니다.
  • EC2 콘솔로 이동하여 ansible-packer 용 EC2에 조금 전에 생성한 role을 부여합니다.

Packer 를 이용해 AMI를 생성합니다.

$ packer build -var-file=var_file.json basic_template.json