Search

Ansible로 시작하는 IaC

Date
2021/06/03
Tags
tags

Ansible이란?

Ansible은 Python으로 구현된 오픈소스 IT 자동화 도구입니다. 간단히 이야기하면 원격지에 있는 여러 서버에 명령어를 실행하는 도구입니다. 쉘스크립트로만 작업을 하면 될 것 같은데 Ansible과 같은 도구를 사용하면 얻는 이점은 무엇일까요? 그 이유는 IaC(Infrastructure as Code)에 있습니다. Ansible은 인프라의 접속정보와 작업명세서를 기록하고 관리함으로써 누구나 동일한 결과를 인프라 변경 작업을 실행할 수 있도록 합니다. 더불어 템플릿과 변수를 활용하여 한 번 작성한 작업명세서(ansible-playbook)을 재사용할 수 있습니다.

Ansible을 주로 사용하는 사례

온프레미스 환경의 리눅스 서버뿐만 아니라 윈도우 서버까지 포함하여 명령어를 사용하는 모든 작업을 처리할 수 있습니다. 온프레미스 환경 뿐만 아니라 AWS, Azure, GCP와 같은 클라우드 서버를 대상으로 작업도 가능합니다.

Ansible의 특징

1. Agentless

•
클라이언트를 별도로 실행할 필요없이 SSH 연결이 가능하다면 바로 사용이 가능합니다. SSH를 사용함에 따라서 Agent 기반의 다른 자동화 오픈소스와 대비하여 속도가 조금 느리다는 단점이 있습니다.

2. 멱등성

•
같은 작업을 몇번이고 수행하더라도 같은 결과가 얻어지는 성격을 가집니다. 예를 들어 데몬(서비스)을 실행하는 작업을 한 번 수행한 이후에 한 번 더 데몬(서비스)를 실행하는 작업을 수행하게 되면 이미 서비스가 실행되어 있는 상태이기 때문에 실제로 작업을 수행하지 않습니다.

3. 쉬운 문법 (Yaml)

•
작업 명세서(Ansible-Playbook)을 YAML 파일로 기술하여 가독성이 높습니다.

4. 변수 활용

•
변수를 사용하여 동일한 작업에 대하여 다른 결과를 만들 수 있습니다.

1. Control Node, Managed Nodes

ansible, ansible-playbook 명령어를 실행하는 주체를 Control Node, 대상 서버를 Managed Nodes라고 합니다.
실행 작업의 종류입니다. ping, copy, template, yum, file 등이 있고 command, shell, raw 등과 같이 사용자가 직접 명령어를 기술할 수 있는 모듈도 있습니다.

3. Inventory

작업 대상 서버가 되는 Managed Nodes를 기술한 파일입니다. 그룹과 인벤토리로 구성되어 있습니다.
[control_server] #group control_server_1 ansible_host=10.0.0.1 #inventory control_server_2 ansible_host=10.0.0.2 #inventory control_server_3 ansible_host=10.0.0.3 #inventory [log_server] #group log_server_1 ansible_host=10.0.0.4 #inventory
Plain Text
복사

4. Tasks

하나의 작업입니다. 다시 말해서 모듈을 사용한 하나의 작업니다. 아래의 예시는 하나의 task로서 특정 경로에 명시된 권한으로 파일을 생성합니다.
- name: Change file ownership, group and permissions file: path: /etc/foo.conf owner: foo group: foo mode: '0644'
YAML
복사

5. Playbooks

inventory를 기반으로 작업 대상과 task를 기술한 작업명세서 입니다. YAML 파일 형식으로 작성되어 있습니다.

Ansible 맛보기

0. Control Node에 Ansible 설치

1. inventory 작성

작업 대상이 될 Manage Nodes를 준비하고 inventory 파일을 작성합니다. 여기서는 3개의 api_server 그룹 내에 api_server_1~3과 같이 3개가 있다고 가정하겠습니다.
# 파일명: inventory [api_server] api_server_1 ansible_host=${ip} api_server_2 ansible_host=${ip} api_server_3 ansible_host=${ip}
Plain Text
복사

2. SSH key 복사

Control Node에서 ssh key를 생성합니다. 생성 후에 작업 대상이 되는 Managed Nodes에 ssh 접속이 될 수 있도록 ssh key를 복사합니다.

3. Ansible Ad-hoc Commands

Ansible Playbook을 작성하지 않더라도 단일 task를 실행할 수 있으며 이를 ad-hoc command라고 합니다. 사용법은 다음과 같습니다.
> ansible -m ${module} -i ${inventory} ${targets} -a ${arguments}
Bash
복사

3-1. ping

백문이 불여일견입니다. ping 모듈을 활용하여 ssh 키가 잘 복사되었고 ssh 접속이 가능한지 테스트할 수 있습니다.
> ansible -i inventory -m ping all # ... api_server_1 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } api_server_2 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } api_server_3 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
Bash
복사
ssh 접속이 잘 된다면 위와 같이 "ping": "pong" 응답이 오게 됩니다. 참고로 all은 모든 인벤토리(여기서는 api_server_1~3)를 의미하는 alias입니다. 특정 그룹이나 인벤토리만 대상으로는 다음과 같이 실행할 수 있습니다.
> ansible -i inventory -m ping api_server > ansible -i inventory -m ping api_server_1 > ansible -i inventory -m ping api_server[1:2] #api_server_2~3
Bash
복사
Control Node에서 known_hosts에 Managed Nodes가 등록이 되어 있지 않은 최초 접속의 경우에는 Are you sure you want to continue connecting (yes/no)? 메세지가 발생하면서 중간에 hang이 걸립니다. 이를 방지하기 위해서는 --ssh-extra-args='-o StrictHostKeyChecking=no 옵션으로 known_hosts 등록을 강제할 수 있습니다.
> ansible -i inventory/hosts.kr-control -m ping all --ssh-extra-args='-o StrictHostKeyChecking=no
Bash
복사

3-2. command

ping에 이어서 command로 원하는 명령어를 실행할 수 있습니다. -a로 원하는 명령어를 전달할 수 있고 간단한 원격작업 실행시에 유용합니다.
> ansible -i inventory -m command -a "hostname -i" api_server api_server_1 | CHANGED | rc=0 >> 10.0.0.1 api_server_2 | CHANGED | rc=0 >> 10.0.0.2 api_server_3 | CHANGED | rc=0 >> 10.0.0.3
Bash
복사
다음과 같이 파일이나 디렉토리를 생성하거나 조회(ls)도 가능합니다.
> ansible -i inventory -m command -a "touch /app/memo.txt" api_server > ansible -i inventory -m command -a "mkdir -p /app/dir" api_server > ansible -i inventory -m command -a "ls -al /app/" api_server
Bash
복사
ssh로 다른 계정으로 접속이 가능할 경우, 다음과 같이 -u 옵션을 통해서 다른 계정으로 접속하여 작업을 진행할 수 있습니다.
# Managed Nodes 3대에 root로 접속하여 yum으로 nginx 설치 > ansible -i inventory -u root -m command -a "sudo yum install -y nginx" api_server
Bash
복사

참고