ansible 미니 프로젝트 ( 사이트 배포 - wordpress를 통한 )


사전구성

vagrant로 구성

 

VM 구성

control: 192.168.110.10 (CentOS7)

node1: 192.168.110.20 (CentOS7)

node2: 192.168.110.30 (CentOS7)

node3: 192.168.110.40 (CentOS7)

node4: 192.168.110.50 (Ubuntu)

node5: 192.168.110.60 (Ubuntu)

 

vagrantfile

더보기
# --- Ansible Server ---

Vagrant.configure("2") do |config|
	config.vm.define "ansible-server2" do |cfg|
		cfg.vm.box = "centos/7" 
		cfg.vm.provider "virtualbox" do |vb|
			vb.name = "ansible-server2"
			vb.cpus = 2
			vb.memory = 4096
			vb.gui = false
		end
		cfg.vm.host_name = "control.example.com"
		cfg.vm.network "private_network", ip: "192.168.110.10"
		cfg.vm.provision "shell", path: "ssh_conf.sh" 
		cfg.vm.synced_folder "../data", "/vagrant", disabled: true
		cfg.vm.provision "shell", inline: "yum -y install epel-release"
		cfg.vm.provision "shell", inline: "yum -y install centos-release-ansible-29.noarch"
		cfg.vm.provision "shell", inline: "yum install ansible -y" # ansible 설치
		cfg.vm.provision "file", source: "ansible_env_ready.yml", # ansible inventory 및 환경설정
			destination: "ansible_env_ready.yml"
		cfg.vm.provision "shell", inline: "ansible-playbook ansible_env_ready.yml"	
		cfg.vm.provision "file", source: "auto_pass.yml", destination: "auto_pass.yml" # 공개키 및 fingerprint 저장
		cfg.vm.provision "shell", inline: "ansible-playbook auto_pass.yml", privileged: false
			
	end
# --- managed node 1 ---
	config.vm.define "my-node1" do |cfg|
		cfg.vm.box = "centos/7" 
		cfg.vm.provider "virtualbox" do |vb|
			vb.name = "node1"
			vb.cpus = 1
			vb.memory = 2048
			vb.gui = false
		end
		cfg.vm.host_name = "node1.example.com"
		cfg.vm.network "private_network", ip: "192.168.110.20"
		cfg.vm.provision "shell", path: "ssh_conf.sh" # ssh(putty) 접속을 위한 설정
		cfg.vm.synced_folder "../data", "/vagrant", disabled: true
	end

# --- managed node 2 ---
	config.vm.define "my-node2" do |cfg|
		cfg.vm.box = "centos/7" 
		cfg.vm.provider "virtualbox" do |vb|
			vb.name = "node2"
			vb.cpus = 1
			vb.memory = 2048
			vb.gui = false
		end
		cfg.vm.host_name = "node2.example.com"
		cfg.vm.network "private_network", ip: "192.168.110.30"
		cfg.vm.provision "shell", path: "ssh_conf.sh"
		cfg.vm.synced_folder "../data", "/vagrant", disabled: true
	end
	
# --- managed node 3 ---
	config.vm.define "my-node3" do |cfg|
		cfg.vm.box = "centos/7" 
		cfg.vm.provider "virtualbox" do |vb|
			vb.name = "node3"
			vb.cpus = 1
			vb.memory = 2048
			vb.gui = false
		end
		cfg.vm.host_name = "node3.example.com"
		cfg.vm.network "private_network", ip: "192.168.110.40"
		cfg.vm.provision "shell", path: "ssh_conf.sh"
		cfg.vm.synced_folder "../data", "/vagrant", disabled: true
	end

# --- managed node 4 - ubuntu ---
	config.vm.define "my-node4" do |cfg|
		cfg.vm.box = "generic/ubuntu2204" 
		cfg.vm.provider "virtualbox" do |vb|
			vb.name = "ubuntu-node4"
			vb.cpus = 1
			vb.memory = 2048
			vb.gui = false
		end
		cfg.vm.host_name = "node4.example.com"
		cfg.vm.network "private_network", ip: "192.168.110.50"
		# cfg.vm.provision "shell", path: "ssh_conf.sh"
		cfg.vm.synced_folder "../data", "/vagrant", disabled: true
	end

# --- managed node 5 - ubuntu ---
	config.vm.define "my-node5" do |cfg|
		cfg.vm.box = "generic/ubuntu2204" 
		cfg.vm.provider "virtualbox" do |vb|
			vb.name = "ubuntu-node5"
			vb.cpus = 1
			vb.memory = 2048
			vb.gui = false
		end
		cfg.vm.host_name = "node5.example.com"
		cfg.vm.network "private_network", ip: "192.168.110.60"
		# cfg.vm.provision "shell", path: "ssh_conf.sh"
		cfg.vm.synced_folder "../data", "/vagrant", disabled: true
	end
end

ansible_env_ready.yml 

- ansible inventory 설정 및 환경설정

더보기
- name: setup for the ansible's environment
  hosts: localhost
  gather_facts: no
  
  tasks:
    - name: add "/etc/hosts"
      blockinfile: 
        path: /etc/hosts
        block: |
          192.168.110.20 node1.example.com node1
          192.168.110.30 node2.example.com node2
          192.168.110.40 node3.example.com node3
          192.168.110.50 node4.example.com node4
          192.168.110.60 node5.example.com node5
          
    - name: add "/etc/ansible/hosts"
      blockinfile: 
        path: /etc/ansible/hosts
        block: |
          [centos]
          node1
          node2
          node3
          
          [ubuntu]
          node4
          node5
            
          [nodes:children]
          centos
          ubuntu
          
    - name: create vim env's directory & files
      shell: "{{item}}"
      loop:
        - "touch /home/vagrant/.vimrc"
        - "touch /home/vagrant/.bashrc"
        
    - name: install vim-enhanced and git
      yum:
        name:                       
          - vim-enhanced 
          - git
        state: present
        
    - name: configure .vimrc
      lineinfile:
        path: /home/vagrant/.vimrc  
        line: autocmd FileType yaml setlocal ai ts=2 sw=2 et  
        
    - name: configure .bashrc
      lineinfile:
        path: /home/vagrant/.bashrc
        line: "{{item}}"
      loop:
        - "alias ans='ansible'"
        - "alias anp='ansible-playbook'"

auto_pass.yml

- ansible 원격 작업을 위한 fingerprint 등록 및 공개키 등록

더보기
- name: Create authority between server and nodes
  hosts: nodes
  connection: local
  serial: 1
  gather_facts: no
  vars:
    ansible_password: vagrant
  tasks: 
    - name: ssh-keyscan for known_hosts file
      command: /usr/bin/ssh-keyscan -t ecdsa {{ ansible_host }}
      register: keyscan
    
    - name: input key
      lineinfile: 
        path: ~/.ssh/known_hosts
        line: "{{ item }}"
        create: yes
      with_items: 
        - "{{ keyscan.stdout_lines }}"

    - name: ssh-keygen for authorized_keys file
      command: "ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N ''"
      ignore_errors: yes
      run_once: true
      
    - name: input key for each node
      connection: ssh
      authorized_key: 
        user: vagrant
        state: present
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

ssh_conf.sh

- CentOS7에 ssh(Putty, MobaXterm)으로 접속하기 위한 설정

** Ubuntu는 설정 안해도 됨. (대신 python 버전을 잡아주는 작업이 필요)

더보기
#/bin/bash
# allow ssh login with password
time=$(date "+%Y%m%d.%H%M%S")
# backup before overwriting
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_$time.backup
sudo sed -i -e 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
sudo systemctl restart sshd

제대로 생성, 설치 및 공개키 등록이 되었는지 확인 하기 위해

"ansible all -m ping" 으로 연결 확인

 

** 문제점으로 Ubuntu 같은 경우에는 CentOS7 와 python 버전이 달라서 공개키가 제대로 안넘어온다.

ssh node4 / ssh node5로 fingerprint를 저장하고

ans ubuntu -m shell -a "sudo ln -s /usr/bin/python3 /usr/bin/python" -k

python3를 python으로 링크를 걸어주고

파워쉘에서 vagrant provision 한번더 해주면 됨.

그 후 

ans ubuntu -m shell -a "sudo unlink /usr/bin/python"

링크 해제해주면 warning 메시지 없이 정상작동함

(전부 vagrantfile에서 할 수 있지만, ad-hoc 연습을 위해 따로 실행)


실습 시나리오

wordpress를 각 노드로 배포하기

1. 먼저 배운대로 apache를 통해 php 사이트로 연결되는 것을 확인할 것이다.

2. 그 이후 wordpress를 다운로드 받아서 wordpress 시작 홈페이지가 들어가 지는것 까지 확인

3. playbook을 role로 변환

 

1. Centos 먼저

1-1. apach, php, mariadb 설치

php.yaml

더보기
[vagrant@control work]$ cat php.yaml
- hosts: centos
  become: yes
  tasks:
    - name: install remirepo to install php 7.4
      yum:
        name:
          - http://rpms.remirepo.net/enterprise/remi-release-7.rpm
          - yum-utils
        state: installed

    - name: epel_release, httpd, php, mariadb install to centos
      yum:
        name:
          - epel-release
          - httpd
          - php
          - php-mysql
          - mariadb
        enablerepo: remi-php74
        state: latest

 

** Ubuntu는 안되는게 생각보다 많기 때문에 일단 CentOS만 먼저 실행해볼것임

 

1-2. 방화벽 설정, 실행 및 index.php 전송

php.yaml에 이어서 작성

더보기
    - name: start firewalld
      service:
        name: firewalld
        state: started

    - name: index.php
      copy:
        src: ~/work/index.php
        dest: /var/www/html/index.php

    - name: restart apache
      service:
        name: httpd
        state: restarted

    - name: restart mariadb
      service:
        name: httpd
        state: restarted


    - name: firewall add service
      firewalld:
        service: http
        permanent: yes
        immediate: yes
        state: enabled

index.php

[vagrant@control work]$ cat index.php
<?php
  phpinfo(); # php 정보 보여주는 페이지(실험용)
?>

 

1-3. php 연결 확인

 

1-4. wordpress 배포

이전에 했던것을 기준으로 할것임

wget https://ko.wordpress.org/latest-ko_KR.tar.gz # 다운받고..
tar -xvf latest-ko_KR.tar.gz -C /var/www/html/wordpress # 압축 해제하고
chown apache:apache # 소유주 그룹권한
chmod 755 /var/www/html/wordpress/ *  # 권한주기
chmod 644 /var/www/html/wordpress/ *.php
web에서 ip주소/wordpress로 접속

 

wordpress.yaml

더보기
    - name: start firewalld
      service:
        name: firewalld
        state: started

    - name: index.php
      copy:
        src: ~/work/index.php
        dest: /var/www/html/index.php

    - name: restart apache
      service:
        name: httpd
        state: restarted

    - name: restart mariadb
      service:
        name: httpd
        state: restarted


    - name: firewall add service
      firewalld:
        service: http
        permanent: yes
        immediate: yes
        state: enabled

안된다.

왜냐면 file 모듈에는 Wildcard (*)이 안된다.

그래서 shell이나 command 모듈을 사용해야 한다.

(다른방법으로 find 모듈을 사용한다음 register로 설정해서 file모듈을 다시 사용할 수는 있으나 그냥 shell을 쓰겠다.)

 

shell을 사용해 권한을 준 wordpress.yaml

더보기
[vagrant@control work]$ cat wordpress.yaml
- hosts: centos
  become: yes
  tasks:
    - name: mkdir ~/work
      file:
        path: ~/work
        state: directory

    - name: download wordpress.tar.gz
      get_url:
        url: https://ko.wordpress.org/latest-ko_KR.tar.gz
        dest: ~/work/wordpress.tar.gz
    - name: unzip
      unarchive:
        src: ~/work/wordpress.tar.gz
        dest: /var/www/html/
        remote_src: yes
    - name: chown
      shell: chown apache:apache /var/www/html/wordpress/*

    - name: chmod
      shell: chmod 755 /var/www/html/wordpress/*

    - name: chmod .php
      shell: chmod 644 /var/www/html/wordpress/*.php

1-5. wordpress 접속 확인

wordpress에 접속하는 방법은 

ip주소/wordpress

(192.168.110.20/wordpress)


2. ubuntu 포함

이젠 ubuntu를 포함해서 해볼 것이다.

 

2-1. apach, php, mariadb 설치

ubuntu가 포함된 php.yaml 

더보기
[vagrant@control work]$ cat php.yaml
- hosts: all
  become: yes
  tasks:
    - name: install remirepo to install php 7.4
      yum:
        name:
          - http://rpms.remirepo.net/enterprise/remi-release-7.rpm
          - yum-utils
        state: installed
      when: ansible_distribution == 'CentOS'

    - name: install remirepo to ubuntu
      apt:
        name:
          - http://rpms.remirepo.net/enterprise/remi-release-7.rpm
          - yum-utils
        state: present
      when: ansible_distribution == 'Ubuntu'

    - name: epel_release, httpd, php, mariadb install to centos
      yum:
        name:
          - epel-release
          - httpd
          - php
          - php-mysql
          - mariadb
        enablerepo: remi-php74
        state: latest
      when: ansible_distribution == 'CentOS'

    - name: apt repo to ubuntu
      shell: add-apt-repository ppa:ondrej/php -y
      when: ansible_distribution == 'Ubuntu'

    - name: upgrade apt
      shell: apt update -y
      when: ansible_distribution == 'Ubuntu'

    - name: httpd, php install to ubuntu
      apt:
        name:
          - apache2 # ubuntu는 httpd가 아닌 apache2
          - php7.4
          - php7.4-mysql
          - mariadb-server
        state: present
      when: ansible_distribution == 'Ubuntu'

2-2. 방화벽 설정, 실행 및 index.php 전송

php.yaml에 이어서 작성

더보기
    - name: start firewalld
      service:
        name: firewalld
        state: started
      when: ansible_distribution == 'CentOS'

    - name: index.php
      copy:
        src: ~/work/index.php
        dest: /var/www/html/index.php

    - name: restart apache centos
      service:
        name: httpd
        state: restarted
      when: ansible_distribution == 'CentOS'

	- name: restart apache Ubuntu
      service:
        name: apache2
        state: restarted
      when: ansible_distribution == 'Ubuntu'

    - name: firewall add service
      firewalld:
        service: http
        permanent: yes
        immediate: yes
        state: enabled
      when: ansible_distribution == 'CentOS'

    - name: enable ufw service
      ufw:
        state: enabled
      when: ansible_distribution == 'Ubuntu'

    - name: ufw add ssh
      ufw:
        rule: allow
        name: OpenSSH
      when: ansible_distribution == 'Ubuntu'

    - name: ufw add apache
      ufw:
        rule: allow
        port: '80'
        proto: tcp
      when: ansible_distribution == 'Ubuntu'

더 줄일 수 있는게 있을 테지만 ubuntu를 써본적이 없기에,

깔끔한것 보다는 구동을 우선시 했기에 다 추가를 해주었다.

 

** ubuntu는 방화벽이 ufw이다.

그리고 name이 centos와 다르기 때문에 잘 확인해야함 (http 이름을 잘 모르겠어서 그냥 port 번호로 작성)

 

2-3. php 연결 확인

 

아마 바로 php화면이 안뜰 수도 있다. 그럴땐

ad-hoc으로 /var/www/html/index.html 을 지워주면 된다.

ansible ubuntu -m shell -a "rm -rf /var/www/html/index.html" --become

 

 

2-4. wordpress 배포

ubuntu를 포함한 wordpress.yaml

더보기
[vagrant@control work]$ cat wordpress.yaml
- hosts: all
  become: yes
  tasks:
    - name: mkdir ~/work
      file:
        path: ~/work
        state: directory

    - name: download wordpress.tar.gz
      get_url:
        url: https://ko.wordpress.org/latest-ko_KR.tar.gz
        dest: ~/work/wordpress.tar.gz

    - name: unzip
      unarchive:
        src: ~/work/wordpress.tar.gz
        dest: /var/www/html/
        remote_src: yes

    - name: chown
      shell: chown apache:apache /var/www/html/wordpress/*
      when: ansible_distribution == 'CentOS'

    - name: chown ubuntu
      shell: chown www-data:www-data /var/www/html/wordpress/*
      when: ansible_distribution == 'Ubuntu'

    - name: chmod
      shell: chmod 755 /var/www/html/wordpress/*

    - name: chmod .php
      shell: chmod 644 /var/www/html/wordpress/*.php

** ubuntu는 권한 소유자 그룹권한이

apache:apache 가 아닌 www-data:www-data 이다.

 

2-5. wordpress 접속 확인

192.168.110.50/wordpress


3. role로 정리하기

 

3-1. roles 디렉터리 생성

ansible-galaxy init roles/php

ansible-galaxy init roles/wordpress

필요없는 잔가지를 치우고 난 뒤 구성 (더 지울 수 있지만, 너무 빈약해 보이기에....)

[vagrant@control work]$ tree
.
└── roles
    ├── php
    │   ├── files
    │   ├── tasks
    │   │   └── main.yml
    │   └── templates
    └── wordpress
        ├── files
        ├── tasks
        │   └── main.yml
        └── templates

 

3-2. php.yaml role로 변환

roles/php/tasks/main.yml

더보기
[vagrant@control ~]$ cat work/roles/php/tasks/main.yml
---
# tasks file for roles/php
- name: install remirepo to install php 7.4
  yum:
    name:
      - http://rpms.remirepo.net/enterprise/remi-release-7.rpm
      - yum-utils
    state: installed
  when: ansible_distribution == 'CentOS'

- name: install remirepo to ubuntu
  apt:
    name:
      - http://rpms.remirepo.net/enterprise/remi-release-7.rpm
      - yum-utils
    state: present
  when: ansible_distribution == 'Ubuntu'

- name: epel_release, httpd, php, mariadb install to centos
  yum:
    name:
      - epel-release
      - httpd
      - php
      - php-mysql
      - mariadb
    enablerepo: remi-php74
    state: latest
  when: ansible_distribution == 'CentOS'

- name: apt repo to ubuntu
  shell: add-apt-repository ppa:ondrej/php -y
  when: ansible_distribution == 'Ubuntu'

- name: upgrade apt
  shell: apt update -y
  when: ansible_distribution == 'Ubuntu'

- name: httpd, php install to ubuntu
  apt:
    name:
      - apache2 # ubuntu는 httpd가 아닌 apache2
      - php7.4
      - php7.4-mysql
      - mariadb-server
    state: present
  when: ansible_distribution == 'Ubuntu'

- name: start firewalld
  service:
    name: firewalld
    state: started
  when: ansible_distribution == 'CentOS'

- name: index.php
  copy:
    src: index.php # 경로 확인 roles/files/index.php
    dest: /var/www/html/index.php

- name: restart apache centos
  service:
    name: httpd
    state: restarted
  when: ansible_distribution == 'CentOS'

- name: restart apache Ubuntu
  service:
    name: apache2
    state: restarted
  when: ansible_distribution == 'Ubuntu'

- name: firewall add service
  firewalld:
    service: http
    permanent: yes
    immediate: yes
    state: enabled
  when: ansible_distribution == 'CentOS'

- name: enable ufw service
  ufw:
    state: enabled
  when: ansible_distribution == 'Ubuntu'

- name: ufw add ssh
  ufw:
    rule: allow
    name: OpenSSH
  when: ansible_distribution == 'Ubuntu'

- name: ufw add apache
  ufw:
    rule: allow
    port: '80'
    proto: tcp
  when: ansible_distribution == 'Ubuntu'

roles/php/files에 index.php 복사하기

[vagrant@control ~]$ cp example/index.php work/roles/php/files/index.php

[vagrant@control ~]$ tree work/
work/
└── roles
    ├── php
    │   ├── files
    │   │   └── index.php # 요거 추가 된거
    │   ├── tasks
    │   │   └── main.yml
    │   └── templates
    └── wordpress
        ├── files
        ├── tasks
        │   └── main.yml
        └── templates

 

3-3 wordpress.yaml role로 변환

roles/wordpress/tasks/main.yml 에 추가

더보기
[vagrant@control ~]$ cat work/roles/wordpress/tasks/main.yml
---
# tasks file for roles/wordpress
- name: mkdir ~/work
  file:
    path: ~/work
    state: directory

- name: download wordpress.tar.gz
  get_url:
    url: https://ko.wordpress.org/latest-ko_KR.tar.gz
    dest: ~/work/wordpress.tar.gz

- name: unzip
  unarchive:
    src: ~/work/wordpress.tar.gz
    dest: /var/www/html/
    remote_src: yes

- name: chown
  shell: chown apache:apache /var/www/html/wordpress/*
  when: ansible_distribution == 'CentOS'

- name: chown ubuntu
  shell: chown www-data:www-data /var/www/html/wordpress/*
  when: ansible_distribution == 'Ubuntu'

- name: chmod
  shell: chmod 755 /var/www/html/wordpress/*

- name: chmod .php
  shell: chmod 644 /var/www/html/wordpress/*.php

3-4. role 실행파일 작성

roles 디렉터리와 같은 경로에 yaml파일 작성

[vagrant@control work]$ cat role_start.yaml
- hosts: all
  become: yes
  roles:
    - php
    - wordpress

 

[vagrant@control work]$ tree
.
├── roles
│   ├── php
│   │   ├── files
│   │   │   └── index.php
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   └── wordpress
│       ├── files
│       ├── tasks
│       │   └── main.yml
│       └── templates
└── role_start.yaml   # 여기에 작성 (사실 다른곳에 해도 실행은 된다만 깔끔하게 이곳에 작성)

끝!

'Ansible' 카테고리의 다른 글

Handler, Template, Role  (0) 2024.02.20
Vault, Facts, Include_tasks, 조건문  (0) 2024.02.19
centos, ubuntu, window node 생성 및 nfs  (0) 2024.02.15
실습  (0) 2024.02.14
Playbook  (0) 2024.02.13

+ Recent posts