Ansible의 playbook 배포를 통해 로드밸런서로 접속하면 두 대의 데이터베이스가 연결되어 있는 워드프레스 웹 서버에 접속할 수 있는 고가용성 시스템을 구성한 후, 해당 고가용성 시스템을 AWX에 올려보는 것을 목표로 본 프로젝트를 진행하였다.
본 프로젝트를 위해 시스템은 총 6개의 노드로 구성하였다.
6개의 노드는 하나의 제어 노드와 5개의 관리 노드로 나누어진다.
하나의 제어 노드 및 5개의 관리 노드의 네트워크 구조는 다음과 같다.
AWX 설치를 위한 명령어
AWX 설치는 controller 노드에서 진행한다.
#1
yum install epel-release
#2
yum install ansible make git nodejs npm python3 python3-pip
#3
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#4
yum install docker-ce docker-ce-cli containerd.io
#5
systemctl enable --now docker
#6
git clone -b 14.0.0 https://github.com/ansible/awx.git
#7
pip3 install docker docker-compose selinux
#8
cd awx/installer
#9
vi inventory
140 project_data_dir=/var/lib/awx/projects
#10
ansible-playbook -i inventory installer.yml -b
위 코드에 대한 설명은 다음과 같다.
#1 epel-release를 설치한다.
#2 AWX를 설치하기 위해 패키지를 설치한다.
#3 최신 Ansible 버전을 사용하기 위해 EPEL Repository를 추가한다.
#4 Docker-ce 관련 패키지를 설치한다.
#5 Docker 서비스를 활성화하고 시작한다.
#6 AWX Git 레포지토리를 적절한 디렉토리에 클론한다.
#7 pip3 모듈을 이용해 Docker 패키지를 설치한다.
#8 awx/installer/inventory 파일의 140번째 줄 주석을 해제한다.
#9 install.yml 플레이북을 실행시켜 AWX를 설치한다.
외부에서 로드밸런서를 통해 웹 서버로 접근하면 웹 서비스를 이용할 수 있고, 두 개의 DB는 Galera module을 통해 서로 데이터를 공유하게 된다.
lb ansible_host=192.168.123.51
web1 ansible_host=192.168.123.52
web2 ansible_host=192.168.123.53
database1 ansible_host=192.168.123.54
database2 ansible_host=192.168.123.55
[lb]
lb
[web]
web1
web2
[db]
database1
database2
[db-master]
database1
[db-slave]
database2
[db-nfs]
database1
#1
#2
- block:
- name: Install epel-release
yum:
name: epel-release
state: latest
- name: Install libsemanage-python for seboolean
yum:
name: libsemanage-python
state: latest
when: ansible_distribution == 'CentOS'
#3
- block:
- name: Update apt cache
apt:
update_cache: yes
when: ansible_distribution == 'Ubuntu'
#1 모든 노드에 epel-release package와 libesemanage-python package를 설치한다.
#2 ansible을 설치한 시스템의 OS가 CentOS일 경우 다음 명령어를 실행한다.
#3 ansible을 설치한 시스템의 OS가 Ubuntu일 경우 다음 명령어를 실행한다.
#1
- name: Add yum_repository for mariadb
yum_repository:
name: MariaDB
baseurl: "{{ mariadb['repo']['baseurl'] }}"
gpgkey: "{{ mariadb['repo']['gpgkey'] }}"
gpgcheck: 1
description: MariaDB
#2
- name: Install mariadb
yum:
name: MariaDB-server
enablerepo: MariaDB
state: latest
- name: Copy mariadb configuration
template:
src: my.cnf.j2
dest: /etc/my.cnf.d/server.cnf
notify:
- Restart mariadb
#3
- name: Start mariadb
service:
name: mariadb
state: started
enabled: true
#4
- name: Install library for DB
yum:
name: MySQL-python
state: latest
#5
- name: Set root password
mysql_user:
login_user: root
login_password: ''
user: root
password: dkagh1.
state: present
#6
- name: Delete anonymous user in DB
mysql_user:
login_user: root
login_password: dkagh1.
name: ''
host_all: yes
state: absent
#7
- name: Delete test db in DB
mysql_db:
login_user: root
login_password: dkagh1.
db: test
state: absent
#8
- name: Create DB for wordpress
mysql_db:
login_user: root
login_password: dkagh1.
name: "{{ mariadb['wp']['name'] }}"
state: present
#9
- name: Create User for wordpress
mysql_user:
login_user: root
login_password: dkagh1.
name: "{{ mariadb['wp']['user'] }}"
password: "{{ mariadb['wp']['pwd'] }}"
priv: "{{ mariadb['wp']['priv'] }}"
host: "{{ mariadb['wp']['host'] }}"
state: present
#10
- name: Open mariadb port
firewalld:
port: "{{ mariadb['port'] }}/tcp"
permanent: yes
state: enabled
immediate: yes
#11
- name: Active seboolean for mysql
seboolean:
name: mysql_connect_any
state: yes
persistent: yes
#1 MariaDB 설치를 위해 레포지토리를 추가한다.
#2 MariaDB를 설치한다.
#3 MariaDB 서비스를 시작한다.
#4 MySQL-python을 설치한다.
#5 root password를 설정한다.
#6 DB의 익명 사용자를 삭제한다.
#7 DB의 test db를 삭제한다.
#8 워드프레스에서 사용할 새로운 DB를 생성한다.
#9 워드프레스에서 사용할 새로운 사용자를 생성하고 권한을 설정한다.
#10 MariaDB와 관련된 방화벽을 열어준다.
#11 MariaDB와 관련된 seboolean을 활성화시킨다.
#1
- name: Install nfs-utils
yum:
name: nfs-utils
state: latest
#2
- name: Create a directory for nfs exports
file:
path: "{{ nfs['exports']['directory'] }}"
state: directory
mode: '0775'
- block:
#3
- name: Create a new primary partition for LVM
parted:
device: "{{ nfs['block']['device'] }}"
number: 1
flags: [ lvm ]
state: present
part_start: 5GiB
#4
- name: Create a filesystem
filesystem:
fstype: "{{ nfs['block']['fs_type'] }}"
dev: "{{ nfs['block']['device'] }}1"
#5
- name: mount /dev/vdb1 on /wordpress
mount:
path: "{{ nfs['exports']['directory'] }}"
src: "{{ nfs['block']['device'] }}1"
fstype: "{{ nfs['block']['fs_type'] }}"
state: mounted
when: nfs['block']['device'] is defined
- name: Create exports to webserver
template:
src: exports.j2
dest: /etc/exports
notify:
- Re-export all directories
#6
- name: Set wordpress url
set_fact:
wp_url: "https://ko.wordpress.org/wordpress-{{ wordpress['source']['version'] }}-{{ wordpress['source']['language'] }}.tar.gz"
wp_filename: "wordpress-{{ wordpress['source']['version'] }}-{{ wordpress['source']['language'] }}.tar.gz"
#7
- name: Download wordpress sources
get_url:
url: "{{ wp_url }}"
dest: "/tmp/{{ wp_filename }}"
#8
- name: Unarchive wordpress archive
unarchive:
src: "/tmp/{{ wp_filename }}"
dest: "{{ nfs['exports']['directory'] }}"
remote_src: yes
owner: root
group: root
#9
- name: Copy wp-config.php
template:
src: wp-config.php.j2
dest: "{{ nfs['exports']['directory'] }}/wordpress/wp-config.php"
#10
- name: Start nfs service
service:
name: nfs
enabled: true
state: started
#11
- name: Allow port for nfs, rpc-bind, mountd
firewalld:
service: "{{ item }}"
permanent: yes
state: enabled
immediate: yes
with_items: "{{ firewall_nfs_lists }}"
#1 NFS 관련 패키지를 설치한다.
#2 export할 디렉토리를 생성한다.
#3 새로운 파티션을 생성한다.
#4 파일시스템을 생성한다.
#5 export 하기 위해 만든 디렉토리로 마운트한다.
#6 wordpress url을 변수로 설정한다.
#7 워드프레스를 다운받는다.
#8 다운받은 워드프레스 파일의 압축을 해제한다.
#9 워드프레스 관련 설정을 수정하기 위해 wp-config-sample.php 파일을 복사한다.
#10 NFS 서비스를 활성화시킨다.
#11 NFS 관련 방화벽을 열어준다.
#1
- name: Install nfs-utils
yum:
name: nfs-utils
state: latest
#2
- name: Install httpd
yum:
name: httpd
state: latest
- name: Copy configuration
template:
src: apache.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- Restart httpd
- name: Delegate collecting facts for mariadb
setup:
delegate_to: node4
- name: Set facts for mariadb private ip
set_fact:
db_private_ip: "{{ ansible_eth1.ipv4.address }}"
#3
- name: Mount nfs share
mount:
path: /var/www/html
src: "{{ db_private_ip }}:{{ nfs['exports']['directory'] }}"
fstype: nfs
state: mounted
#4
- name: Open http port
firewalld:
port: "{{ apache['port'] }}/tcp"
permanent: yes
state: enabled
immediate: yes
#5
- name: Active seboolean for httpd
seboolean:
name: "{{ item }}"
state: yes
persistent: yes
with_items: "{{ sebool_httpd_lists }}"
#6
- name: Install remi-release-7 for php74
yum:
name: "{{ php['repo']['pkg'] }}"
state: latest
- name: Install php and php-mysql
yum:
name: php,php-mysql
enablerepo: remi-php74
state: latest
#7
- name: Start httpd
service:
name: httpd
state: started
enabled: true
#1 NFS 패키지를 설치한다.
#2 httpd를 설치한다
#3 공유 디렉토리를 /var/www/html에 마운트한다.
#4 http 방화벽을 열어준다.
#5 httpd와 관련된 seboolean을 활성화시킨다.
#6 php를 설치한다.
#7 apache 서비스를 시작한다.
- name: Deploy to CentOS
block:
#1
- name: Install haproxy
yum:
name: haproxy
state: latest
#2
- name: Open http port
firewalld:
port: "{{ haproxy['frontend']['port'] }}/tcp"
permanent: yes
state: enabled
immediate: yes
#3
- name: Active seboolean for httpd
seboolean:
name: haproxy_connect_any
state: yes
persistent: yes
- name: Set facts for haproxy public ip
set_fact:
haproxy_public_ip: "{{ ansible_eth0.ipv4.address }}"
- name: Delegate collecting facts for wordpress1
setup:
delegate_to: node2
- name: Set facts for wordpress1 private ip
set_fact:
wordpress1_private_ip: "{{ ansible_eth1.ipv4.address }}"
- name: Delegate collecting facts for wordpress2
setup:
delegate_to: node3
- name: Set facts for wordpress2 private ip
set_fact:
wordpress2_private_ip: "{{ ansible_eth1.ipv4.address }}"
- name: Copy haproxy configuration
template:
src: centos/haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify:
- Restart haproxy service
when: ansible_distribution == "CentOS"
#4
- name: Start haproxy service
service:
name: haproxy
enabled: true
state: started
#1 haproxy를 설치한다.
#2 haproxy의 프론트엔드 포트를 설정한다.
#3 http와 관련된 seboolean을 활성화시킨다.
#4 aproxy 서비스를 시작한다.
mariadb:
#1
repo:
baseurl: http://mirror.yongbok.net/mariadb/yum/10.5/centos7-amd64
gpgkey: http://mirror.yongbok.net/mariadb/yum/RPM-GPG-KEY-MariaDB
#2
wp:
name: wordpress_db
user: admin
pwd: dkagh1.
priv: wordpress_db.*:ALL,GRANT
host: '192.168.123.%'
port: 3306
#1 mariadb 설치를 위해 추가할 레포지토리의 주소를 변수로 설정해준다.
#2 mariadb에서 지정할 워드프레스 관련 설정을 변수로 만들어주었다.
nfs:
#1
exports:
directory: /wordpress
subnet: 192.168.123.0/24
options: rw,sync,no_root_squash
#2
block:
#device: /dev/vdb
fs_type: ext4
#1 nfs 서버에서 export할 디렉토리와 관련된 정보들을 변수로 설정해준다.
#2 nfs 서버에서 새롭게 생성할 블록 장치의 파일시스템 타입을 설정해준다.
#1
sebool_httpd_lists:
- httpd_can_network_connect
- httpd_can_network_connect_db
- httpd_use_nfs
#2
apache:
port: 80
#3
php:
repo:
pkg: "https://rpms.remirepo.net/enterprise/remi-release-7.rpm "
#1 apache 웹 서버에서 허용할 seboolean을 반복문으로 지정해주기 위해 다음과 같이 설정한다.
#2 apache 웹 서버에서 허용할 포트를 지정한다.
#3 php 설치를 위해 repo 주소를 지정한다.
#1
haproxy:
frontend:
port: 80
backend:
name: wordpress
balance_type: roundrobin
wordpress1:
port: 80
wordpress2:
port: 80
#1 haproxy 서버에서 내부로 접근하기 위해 다음과 같이 포트를 지정한다.
자격증명은 제어 노드에서 관리 노드에 접근할 때 사용하는 인증 값이다.
다음과 같은 순서로 자격증명을 진행할 수 있다.
AWX 대시보드의 왼쪽 메뉴 중 Credential로 들어온 후 [+] 버튼(Create a new credential)을 클릭한다.
Name, Organization, Credential Type, Username을 순서대로 입력한다.
컨트롤 머신에서 ssh private key를 확인한 후 SSH PRIVATE KEY 칸에 입력한다.
NAME 칸에 입력한 이름(new student)과 같게 새로운 자격증명이 생성된다.
AWX의 프로젝트는 플레이북의 모음이다.
다음과 같은 순서로 새로운 프로젝트를 생성할 수 있다.
AWX 대시보드의 왼쪽 메뉴 중 Projects로 들어온 후 [+] 버튼(Create a new credential)을 클릭한다.
새로운 프로젝트를 생성하기 위해 Name, Organization, SCM Type, Playbook Directory를 순서대로 입력한다.
Project Base Path는 플레이북이 존재하는 디렉토리 경로로 Project Base Path를 지정하기 위해서 tower가 설치된 머신의 /var/lib/awx/project에 디렉토리를 생성해야한다.
/var/lib/awx/project 밑에 /test_project 디렉토리를 생성하였고 다음과 같이 지정해주었다.
새로운 프로젝트가 생성되었다.
AWX의 인벤토리는 Ansible의 인벤토리와 같고, AWX에서는 인벤토리를 그래픽으로 관리할 수 있다는 장점이 있다. Ansible의 컨트롤 머신에서 생성한 인벤토리 파일의 내용과 동일하게 AWX에서도 다음과 같이 그룹과 호스트를 지정해주었다.
본 프로젝트는 미완성된 프로젝트로 보완해야할 점이 많이 남아있다.
보완이 필요한 사항은 첫번째, AWX에서 자격증명, 프로젝트, 인벤토리 생성은 완료했지만 컨트롤 머신에서 제작한 role 디렉토리와 관련된 템플릿은 올려보지 못했다는 점이다.
두번째, 컨트롤 머신에서 작성한 yaml, 템플릿, 변수 파일은 강사님의 코드를 대부분 참고하여 작성한 파일들로 스스로 해당 파일의 내용을 작성해볼 수 있도록 ansible의 활용과 관련된 여러 주제들을 다시 복습해야할 필요가 있다.
와..인프라 분야는 저에게 생소해서 잘 모르지만, 한 주 동안 엄청 열심히 하신 것 같아 자극됩니다.
또 목표/구성/결과 등으로 나누어 글을 작성하신 점도 본받아야겠다는 생각이 드네요! 글 공유 감사합니다~