메뉴 닫기

Ansible 이용한 Apache 서버 제어

“Ansible를 이용한 Apache 서버 제어”


Ansible(앤서블)은 여러 개의 서버를 효율적으로 관리할 수 있게 해주는 IT 환경 구성 자동화 도구이다.

Ansible(앤서블)은 시스템 구성하고, 소프트웨어 배포하고, 지속적인 배포 또는 제로 다운 타임 롤링 업데이트와 같은 고급 IT 작업이 가능하다.
앤서블은 플레이북 이라는 곳에 실행할 구성을 선언해 놓으면, 필요할 때 마다 자동으로 실행 시킬 수 있는 것이 가장 큰 특징이다. 웹서버의 구성 등을 선언해 놓으면 관리자들은 필요할 때마다 그 구성대로 서버의 설정을 베포 할 수 있게 해주는 것이다.
또한 멱등성(Idempotency, 여러 번 적용해도 결과가 동일하며, 수정된 부분이 있다면 그 부분만 새롭게 반영 됨. 예를들어 install java 명령어 실행 시 이미 해당 서버에 java가 설치되어 있으면 재 설치하지 않음)의 특징이 있으며, 데이터 전송을 위해 OpenSSH를 이용하고, yaml 언어를 사용한다.

이 포스팅에서는 Ansible를 이용한 Apache 서버 제어하는 방법(VirtualHost, SSL)을 설명합니다.

[개 요]

✅종    류 : 엔지니어링 
✅난이도 : ⭐ ⭐ 
✅내용요약 : Ansible를 이용한 타 서버 Apache 서버 제어 방법 설명
✅테스트 환경 : Ubuntu 22.04 (Debian) 마스터서버 1대 + Ubuntu 22.04 (Debian) Web서버 1대
✅관련직무 : 시스템&클라우드 엔지니어

“시작하며”

 

    👉Ansible에 관련 설명 바로가기


 이 포스트는 Ansible를 이용한 Apache 서버 제어 적용 방법 과 활용사례에 대해 아래 순서로 설명합니다.

    1. 마스터서버에서 Ansible 과 ssh-keygen 설치

    2. ssh-keygen 생성 및 배포

    3. Ansible 제어노드, 인벤토리, 플레이북 생성

    4. Ansible적용 및 실행

    5. 호스트 WEB 서버에서 확인

 

1) 마스터서버에서 Ansible과 ssh-keygen 설치


Ansible을 사용하기 위해서 마스터서버에서 설치를 진행합니다.

 

 
[root@localhost]# apt update -y
[root@localhost]# apt upgrade -y
[root@localhost]# apt install -y ansible sshpass tree

 

2) ssh-keygen 생성 및 배포


저장소를 추가하고 활성화 하기 위해 아래의 작업을 수행합니다.

 

[root@localhost]# ssh-copy-id root@WEB서버IP

 

sshpass를 설치를 진행하였으니, ssh-keygen 작업을 진행합니다.

 
[root@localhost]# ssh-keygen

 

ssh-key를 만들때 여러번 묻는 상황이 나옵니다. 해당 부분에 아무것도 입력하지 않고 엔터 키보드만 누르면 됩니다.

아래 그림처럼 하면 key가 생성됩니다.

 

 

 

 

 

 

3) Ansible  제어노드, 인벤토리, 플레이북 생성


환경변수 설정을 위해 아래 작업을 수행합니다. 일단 디렉토리 구조체부터 생성합니다.

[root@localhost]# mkdir /root/ansible_project
[root@localhost]# cd /root/ansible_project
[root@localhost]# mkdir -p playbooks/handlers/ playbooks/templates/ playbooks/roles/common/tasks playbooks/roles/web/tasks playbooks/db/common/tasks

ansible directory

 

 

 

 

 

인벤토리 생성

[root@localhost]# vi /root/ansible_project/inventory.ini

master ansible_host=10.0.0.2

[web]
web ansible_host=10.0.0.3

[db]
db ansible_host=10.0.0.4

 

playbooks 설정 (WEB, DB)

 

vi /root/ansible_project/playbooks/configure_web.yml

- name: Configure Web Server
  hosts: web
  become: true
  roles:
    - common
    - web
  handlers:
   - name: Reload Apache
     import_tasks: handlers/main.yml

 

vi /root/ansible_project/playbooks/configure_db.yml

- name: Configure Database Server
  hosts: db
  become: true
  roles:
    - common
    - db

 

Apache Virtual Host 설정

vi /root/ansible_project/playbooks/add_vhost.yml

- name: Add Virtual Hosts
  hosts: web
  become: true
  vars:
    domain_name: "93it-serverengineer.kr"
    document_root: "/home/93it/www"
  tasks:
    - name: Create directory for the virtual host
      file:
        path: "{{ document_root }}"
        state: directory
        mode: '0755'
      become: true

    - name: Create index.html file
      copy:   web
      content: "93it-serverengineer.kr index.html"
        dest: "{{ document_root }}/index.html"
      become: true

    - name: Create phpinfo.php file
      copy:
        content: "93it-serverengineer.kr phpinfo.php <?php phpinfo();?>"
        dest: "{{ document_root }}/phpinfo.php"
      become: true

    - name: Create Apache virtual host configuration
      template:
        src: vhost.conf.j2
        dest: "/etc/apache2/sites-available/{{ domain_name }}.conf"
      notify:
        - Reload Apache

    - name: Enable the virtual host
      command: "a2ensite {{ domain_name }}"
      args:
        creates: "/etc/apache2/sites-enabled/{{ domain_name }}.conf"
      notify:
        - Reload Apache
  handlers:
  - name: Reload Apache
    import_tasks: handlers/main.yml

 

SSL 노트 설정

vi /root/ansible_project/playbooks/letsencrypt.yml

---
- name: Add Virtual Hosts and SSL Certificates
  hosts: web
  become: true
  vars:
    domains:
      - "93it-serverengineer.kr"
    document_root: "/home/93it/www"

# letsencrypt.yml

  handlers:
    - import_tasks: handlers/main.yml

  tasks:
    - name: Install Certbot and Apache plugin
      apt:
        name:
          - certbot
          - python3-certbot-apache
        state: present

    - name: Check if Certbot renewal configuration file exists
      stat:
        path: "/etc/letsencrypt/renewal/{{ item }}.conf"
      register: certbot_renewal_info
      with_items: "{{ domains }}"
      ignore_errors: yes

    - debug:
        var: certbot_renewal_info

    - name: Renew Let's Encrypt SSL certificates if domains.conf doesn't exist
      command: "certbot certonly --webroot -w {{ document_root }} -d {{ item }} --email resave177@naver.com --agree-tos --no-eff-email --rsa-key-size 4096"
      with_items: "{{ domains }}"
      when: "not certbot_renewal_info is defined or (certbot_renewal_info.results | default([]) | map(attribute='stat.exists') | bool)"
      ignore_errors: yes

    - name: Create SSL virtual host configuration
      template:
        src: ssl_vhost.conf.j2
        dest: "/etc/apache2/sites-available/{{ item }}-ssl.conf"
      with_items: "{{ domains }}"
      notify:
        - Reload Apache

    - name: Enable SSL virtual host
      command: "a2ensite {{ item }}-ssl.conf"
      args:
        creates: "/etc/apache2/sites-enabled/{{ item }}-ssl.conf"
      with_items: "{{ domains }}"
      notify:
        - Reload Apache

  handlers:
    - name: Restart Cron
      systemd:
        name: cron
        state: restarted

    - name: Add Certbot renewal and Apache reload to /etc/crontab
      blockinfile:
        path: "/etc/crontab"
        block: |
          0 4 * * * root certbot renew --quiet
          1 4 * * * root systemctl reload apache2
        marker: "# {mark} Ansible managed block"
      notify:
        - Restart Cron

 

Apache 재시작 핸들러

vi /root/ansible_project/playbooks/handlers/main.yml

---
- name: Reload Apache
  service:
    name: apache2
    state: reloaded

 

Vhost 설정 생성할때 설정

vi /root/ansible_project/playbooks/templates/vhost.conf.j2
vi /root/ansible_project/playbooks/roles/web/templates/vhost.conf.j2

<VirtualHost *:80>
    ServerAdmin webmaster@{{ domain_name }}
    ServerName {{ domain_name }}
    DocumentRoot {{ document_root }}

    ErrorLog ${APACHE_LOG_DIR}/{{ domain_name }}_error.log
    CustomLog ${APACHE_LOG_DIR}/{{ domain_name }}_access.log combined

    <Directory {{ document_root }}>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

        # PHP settings
        <FilesMatch \.php$>
            SetHandler application/x-httpd-php
        </FilesMatch>
    </Directory>

</VirtualHost>

 

SSL Vhost 설정 생성할때 설정

vi /root/ansible_project/playbooks/templates/ssl_vhost.conf.j2

vi /root/ansible_project/playbooks/roles/web/templates/vhost.conf.j2

<IfModule mod_ssl.c>
    {% for domain in domains %}
    <VirtualHost *:443>
        ServerAdmin webmaster@{{ domain }}
        ServerName {{ domain }}
        DocumentRoot {{ document_root }}

        ErrorLog ${APACHE_LOG_DIR}/{{ domain }}_ssl_error.log
        CustomLog ${APACHE_LOG_DIR}/{{ domain }}_ssl_access.log combined

        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/live/{{ domain }}/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/{{ domain }}/privkey.pem
        SSLCertificateChainFile /etc/letsencrypt/live/{{ domain }}/fullchain.pem

    <Directory {{ document_root }}>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

        # PHP settings
        <FilesMatch \.php$>
            SetHandler application/x-httpd-php
        </FilesMatch>
    </Directory>

    </VirtualHost>
    {% endfor %}
</IfModule>

 

vi /root/ansible_project/playbooks/roles/common/tasks/main.yml

---
- name: Install common packages
  apt:
    name: "{{ item }}"
    state: present
  with_items:
    - curl
    - vim
    # Add other common packages as needed

- name: Ensure time is synchronized
  apt:
    name: ntp
    state: present
  become: true

 

vi /root/ansible_project/playbooks/roles/db/tasks/main.yml

---
- name: Install MariaDB Server
  apt:
    name: mariadb-server
    state: present

- name: Enable MariaDB service
  service:
    name: mariadb
    enabled: yes
    state: started

 

vi /root/ansible_project/playbooks/roles/web/tasks/main.yml

---
- name: Install Apache
  apt:
    name: apache2
    state: present

- name: Enable Apache service
  service:
    name: apache2
    enabled: yes
    state: started

- name: Ensure Apache modules are enabled
  apache2_module:
    state: present
    name: "{{ item }}"
  with_items:
    - rewrite
    - headers
    - ssl
    - socache_shmcb
    - socache_dbm
  notify:
    - Reload Apache

- name: Install PHP 8.1 and Apache PHP module
  apt:
    name:
      - php8.1
      - libapache2-mod-php8.1
    state: present
  notify:
    - Reload Apache

 

vi /root/ansible_project/playbooks/roles/web/templates/php.ini.j2

vi /root/ansible_project/playbooks/templates/php.ini.j2

; PHP settings
display_errors = On
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
date.timezone = UTC

 

4) ansible로 호스트 WEB서버 VirtualHost , SSL 인증서 적용시키기


cd /root/ansible_project
ansible-playbook -i inventory.ini playbooks/configure_web.yml
ansible-playbook -i inventory.ini playbooks/configure_db.yml
ansible-playbook -i inventory.ini playbooks/add_vhost.yml
ansible-playbook -i inventory.ini playbooks/letsencrypt.yml

ansible 실행

 

 

 

 

 

ansible Virtualhost

 

 

 

 

ansible SSL

 

 

 

 

 

 

 

 

5) 호스트 WEB 서버에서 확인


# apache2ctl -S

Virtual Host

 

 

 

 

 

 

 

WEB 서버에서 Virtual 도메인과 SSL인증서 발급되었습니다

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x