가시다님 주관 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 설정을 진행해줘야 한다.
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
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이다.
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
'DevOps' 카테고리의 다른 글
[Grafana Loki] 청크 중복성 제거하기 (ingester에만 chunk cache 적용) (0) | 2024.05.10 |
---|---|
[Strimzi Kafka Connect] 손쉽게 커넥터 Config에 시크릿 적용하기 (0) | 2024.05.01 |
[Ansible] 반복문, 조건문, 핸들러, 블록, Recsue 등 개념 정리 (0) | 2024.01.20 |
[Ansible] 기본 개념 정리 (0) | 2024.01.09 |
[AWS] 클라우드 와치 로그에서 특정 패턴일 경우 Slack 알람 보내는 방법 (0) | 2023.07.02 |