본문 바로가기

DevOps

[Ansible] 사용자 계정 생성 및 apache http 설치 실습

반응형

가시다님 주관 A101 스터디에 대한 정리 - 3주차 입니다.

 

1, 2 주차에는 Ansible 개념에 대해 전반적으로 알아보았습니다.

 

이번 주차에는 간단한 실습을 진행해봅니다. 추가로 valut 암호화 시 aws secrets manager를 활용해보겠습니다.

 

실습 환경에 대한 설명은 따로 하지 않음


 

1. 사용자 계정 생성 실습

원격 서버에 사용자 계정을 Playbook, 암호화를 활용하여 생성해보자.

 

# 아이디어

- ansible.builtin.user 모듈을 사용하면 될 것 같다.

- ansible은 ansible-vault를 통해 암호화를 수행할 수 있다.

    >> playbook 안에 username, password를 직접 넣어 만들수도 있지만 이는 보안에 취약하다.

    >> 따라서 별도 file에 username, password 정보를 기입하고 이를 암호화한뒤 ansible-playbook을 실행할 때 이 파일을 참조하면 되지 않을까?

 

 

1. ansible.cfg 생성

user 모듈을 사용하기 위해서는 원격 노드의 root privilege가 있어야 한다.

따라서 privilege_escalation 섹션에서 become 설정을 진행해줘야 한다.

[defaults]
inventory = ./inventory
remote_user = ubuntu
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

 

 

inventory 설명은 생략한다.

 

이제 username, password 정보가 담긴 파일을 만들어보자.

 

ansible-vault 명령어를 통해 암호화된 파일을 만들 수 있다.

 

ansible-vault create vars/secret.yml

 

 

패스워드를 기입하면 코드창으로 전환되는데 yaml 포맷으로 변수를 설정한 뒤 wq로 빠져나오면 된다.

 

---

user_info:
  - userid: "ansible"
    userpw: "ansiblePw1"
  - userid: "stack"
    userpw: "stackPw1"

 

 

해당 파일은 이제 암호화가 되었기 떄문에 ansible-valut password를 알아야지만 암호화된 파일을 사용할 수 있게 된다.

 

 

 

ansible-vault --help를 쳐보면 사용 가능한 인자에 decrypt가 있는데 이를 사용하면 복호화를 할 수 있다.

 

또한 view를 사용하면 해당 파일의 암호화를 그대로 설정해둔 채 일회성으로 내용을 확인할수도 있다.

 

 

 

이제 Playbook을 만들어보자.

 

 

크게 어려운 내용이 없지만 user module을 사용할 때 state: present(계정 생성) 이라면 password는 hashed가 되어 있어야 한다.

 

(참고)

https://stackoverflow.com/questions/19292899/creating-a-new-user-and-password-with-ansible

 

Creating a new user and password with Ansible

I have an ansible task which creates a new user on ubuntu 12.04; - name: Add deployment user action: user name=deployer password=mypassword it completes as expected but when I login as that u...

stackoverflow.com

 

 

 

 

1. 1. 사용자 계정 생성 - 검증 및 수행

 

ansible-playbook 명령어는 문법을 검사할 수 있는 --syntax-check 옵션을 제공한다.

 

해당 옵션을 적용한 뒤 ansible-playbook을 돌려보니 다음의 에러가 발생한다.

ERROR! Attempting to decrypt but no vault secrets found

 

 

이는 우리가 사용하는 vars/secret.yml 파일이 vault 암호화가 되어 있기 때문인데 이 때 ansible-playbook을 실행할 때 vault password를 물어보도록 하는 옵션을 넣어주면 된다.

 

 

 

문법엔 문제가 없는 것을 확인했으니 ansible을 실행해보자.

 

 

원격 노드에 계정들이 잘 생성된 것을 확인할 수 있다.

 

 

 

 

2. valut + AWS Secrets Manager 연동

ansible-vault를 사용할 때 --ask-valut-pass 옵션을 사용하면 되긴 하지만 만약 완전한 IaC를 수행하기 위해 vault-password 파일 또한 File로 보관하길 원한다면 어떻게 해야 할까?

 

ansible-playbook에는 --vault-password-file 옵션을 제공한다.

 

 

하지만 이 방법 또한 결국 Git 같은 곳에 아무런 생각 없이 Push를 하게 된다면 패스워드가 그대로 노출될 수 있다는 단점이 존재한다.

 

그렇다면 이를 해결할 수 있는 방안은 무엇이 있을까? 바로 Ansible vault + AWS Secrets Manager를 연동하는 방법이다.

 

--valut-password-file은 Shell Script를 사용할 수 있는데 이를 통해 실제 valut password는 AWS Secrets Manager에 등록하고 이를 참조하여 복호화를 진행하는 방법이다.

 

 

 

 

aws secrets manager가 생성된 것을 확인

 

 

이렇게 shell script를 활용하게 되면 -> Git에 Push하게 되어도 민감정보가 저장되지 않게 된다.

 

 

권한을 확인한 뒤 의도한대로 값이 출력되는지 확인해보자.

 

값이 잘 출력된다면 ansible-playbook을 안전하게 수행할 수 있게 된다.

 

 

3.  Apache HTTP 패키지 설치 - Ansible Role 사용

tnode4 EC2가 하나 더 추가되었다고 가정해보자. 참고로 이 노드는 Ubuntu가 아니라 Amazon Linux2이다.

 

/etc/hosts에 추가

 

 

OS 별로 Play를 다르게 설정하는 부분만 간단히 확인할 예정이기 때문에 인증 처리를 아래와 같이 임시로 해두었다.

 

 

 

# 3.1. role 생성

ansible-galaxy init --init-path ./roles apache.http

 

 

## 3.2. 구조 확인

 

우리가 여기서 사용할 파일들은 다음과 같다.

handlers/main.yml : httpd 서비스를 재시작 할 경우 handler 호출

 

tasks/main.yml : Main Task를 정의하는 파일이며 해당 파일에는 각 Sub Task들을 호출하게 된다.

tasks/ubuntu.yml : Ubuntu에서 apt 모듈을 활용하여 apache를 설치하게 된다.

tasks/amz2.yml : AMZ2에서 yum 모듈을 활용하여 apache를 설치하게 된다.

 

templates/main.html : html 파일을 간단히 옮김

 

 

 

 

최상단 apache-playbook.yml : role을 참조하게 되는 playbook이다.

---

- hosts: all
roles:
- role: apache

 

 

 

 

handlers/main.yml

: httpd 서비스를 재시작하는 handler

---
# handlers file for apache

- name: Start httpd 
  ansible.builtin.service:
    name: httpd
    state: started

 

 

 

 

tasks/main.yml

: 메인 task yaml이다. 각 OS distribution에 맞는 yml 파일을 import 한 뒤에 copy를 수행한다.

 

---
# tasks file for apache

# 1. import playbook
- name: "Import {{ ansible_facts.distribution }} playbook"
  ansible.builtin.include_tasks:
    file: "{{ ansible_facts.distribution }}.yml"

# 2. copy
- name: Copy index file when Ubuntu
  ansible.builtin.template:
    src: index.html
    dest: /var/www/html/index.html
  when: ansible_facts.distribution == "Ubuntu"

- name: Copy index file when Amazon
  ansible.builtin.template:
    src: index.html
    dest: /var/www/html/index.html
  when: ansible_facts.distribution == "Amazon"

 

 

Amazon일 경우 notify를 통해 handler를 호출한다. yum 모듈을 사용한다.

---

- name: Install the latest version of Apache in Amazon
  ansible.builtin.yum:
    name: httpd
    state: present
  notify: Start httpd

 

 

Ubuntu일 경우 apache2를 설치한다.

---

- name: Install the latest version of Apache in Ubuntu
  ansible.builtin.apt:
    name: apache2
    state: present

 

 

index.html은 대충 만들어주자.

 

 

3.2. 실행해보기

첫 번째 실행할 때에는 tnode1만 대상으로 실행하였고 두 번째 실행할 때는 all을 대상으로 실행하였다.

 

멱등성을 보장하기 때문에 tnode1은 OK 혹은 Skipping이 뜨는 것을 확인할 수 있다.

 

 

 

Ref

https://ho-story.tistory.com/341

https://www.youtube.com/watch?v=N2wzqgkUYD0

반응형