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

ansibleansible-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
복사

참고