【ハンズオン】GitLabおよびAnsibleによるインフラCI/CD ~Step3.Playbook適用~

はじめに

アプリケーション開発においては、CI/CDの活用が広く一般化していますが、インフラレイヤにおけるCI/CDについては、いまだ導入が進んでいない現場も多いと感じています。
本シリーズでは、GitLabとAnsibleを用いたインフラCI/CDの導入例を、ハンズオン形式でご紹介しています。ぜひ参考にしていただければ幸いです。
今回は最終回となるステップ3として、AnsibleのPlaybook作成と、GitLab Runnerを用いた環境への適用方法についてご紹介します。
ステップ1、2を読んでない方はぜひ読んでみて下さい。
【ハンズオン】GitLabおよびAnsibleによるインフラCI/CD ~Step1.導入目的~
【ハンズオン】GitLabおよびAnsibleによるインフラCI/CD ~Step2.環境構築~

1. AnsibleのPlaybook作成

今回作成するPlaybookのディレクトリ/ファイル構成を下記に示します。順を追って作成していきましょう。


├── ansible.cfg
├── site.yml
├── websystem_install.yml
├── websystem
│   ├── inventory
│   │   ├── dev_inventory.ini
│   │   └── prod_inventory.ini
│   └── roles
│       ├── apache
│       │   ├── files
│       │   │   └── httpd.conf
│       │   ├── tasks
│       │   │   ├── check_install.yml
│       │   │   ├── configure.yml
│       │   │   ├── install.yml
│       │   │   └── main.yml
│       │   ├── tests
│       │   └── vars
│       │       └── main.yml
│       ├── app
│       │   ├── files
│       │   │   └── ROOT.war
│       │   ├── tasks
│       │   │   ├── configure.yml
│       │   │   └── main.yml
│       │   ├── tests
│       │   └── vars
│       │       └── main.yml
│       ├── common
│       │   ├── files
│       │   │   └── profile
│       │   ├── tasks
│       │   │   └── main.yml
│       │   └── vars
│       ├── postgres
│       │   ├── files
│       │   │   ├── data.sql
│       │   │   ├── pg_hba.conf
│       │   │   ├── postgresql.conf
│       │   │   └── table.sql
│       │   ├── tasks
│       │   │   ├── check_install.yml
│       │   │   ├── configure.yml
│       │   │   ├── install.yml
│       │   │   └── main.yml
│       │   ├── tests
│       │   └── vars
│       │       └── main.yml
│       └── tomcat
│           ├── files
│           │   ├── context.xml
│           │   ├── server.xml
│           │   ├── setenv.sh
│           │   └── tomcat.service
│           ├── tasks
│           │   ├── check_install.yml
│           │   ├── configure.yml
│           │   ├── install.yml
│           │   └── main.yml
│           ├── tests
│           └── vars
│               └── main.yml
1.1 共通ymlファイル

ansible-playbookコマンドを実行する際に指定するsite.ymlファイルを作成します。

[ansible@git-server ~]$ vi site.yml
[ansible@git-server ~]$ cat site.yml
---
# file: site.yml
- import_playbook: websystem_install.yml
[ansible@git-server ~]$

続いてsite.ymlで呼び出しているwebsystem_install.ymlファイルを作成します。下記の通りroleおよびtagを設定しています。

[ansible@git-server ~]$ vi websystem_install.yml
[ansible@git-server ~]$ cat websystem_install.yml
---
- name: Install for web system
  hosts: websystem
  become: true
  roles:
    - { role: common, tags: common }        ##OS setting
    - { role: postgres, tags: postgres }    ##Postgres Install/setting
    - { role: tomcat, tags: tomcat }        ##Tomcat Install/setting
    - { role: apache, tags: apache }        ##Apache Install/setting
[ansible@git-server ~]$
1.2 OS設定

まずはOS関連の共通設定に関するymlファイルを作成していきましょう。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/common/tasks/main.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/common/tasks/main.yml
---
# tasks file for ./roles/common

# 1.SELinuxの無効化
- name: configure / Disable SELinux in config file
  ansible.builtin.lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: 'SELINUX=disabled'
    state: present
  become: true

- name: configure / Set SELinux to permissive temporarily (until reboot)
  ansible.builtin.command: setenforce 0
  when: ansible_selinux is defined and ansible_selinux.status == 'enabled' and ansible_selinux.mode == 'enforcing'
  become: true

# 2.パッケージの最新化
- name: configure / Update yum packages
  ansible.builtin.dnf:
    name: "*"
    state: latest
  become: true

# 3.EPEL Repository登録
- name: configure / Import EPEL Repository
  yum:
    name: epel-release
    state: latest
    update_cache: yes
  become: true

# 4.環境変数設定
- name: configure / deploy profile file
  copy:
    src: profile
    dest: /etc/profile
    owner: root
    group: root
    mode: 0644
  become: true
[ansible@git-server ~]$

事前に準備した/etc/profileファイルをコントロールノード側にアップロードします。

[ansible@git-server ~]$ ls -l /home/ansible/websystem/roles/common/files/
total 4
-rw-r--r-- 1 ansible ansible 2023 Mar  2 06:55 profile
[ansible@git-server ~]$

下記の通りJavaアプリケーションを起動させるための環境変数設定を入れておきます。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/common/files/profile
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/common/files/profile
# /etc/profile
~省略~

#デフォルトから下記を追加
export JAVA_HOME=/opt/java/jdk-21.0.6
export JRE_HOME=$JAVA_HOME
export PATH="$JAVA_HOME/bin:/opt/maven/default/bin:$PATH"
1.3 PostgreSQLインストール/設定/データ登録

続いてPostgreSQLのインストール、設定およびデータ登録をしていきます。まずは必要なディレクトリを作成してください。

[ansible@git-server ~]$ mkdir -p /home/ansible/websystem/roles/postgres/files
[ansible@git-server ~]$ mkdir -p /home/ansible/websystem/roles/postgres/tasks
[ansible@git-server ~]$ mkdir -p /home/ansible/websystem/roles/postgres/vars
[ansible@git-server ~]$ mkdir -p /home/ansible/websystem/roles/postgres/tests
[ansible@git-server ~]$
[ansible@git-server ~]$ tree
##抜粋
.
├── websystem
│   ├── inventory
│   │   └── inventory.ini
│   └── roles
│       └── postgres
│           ├── files
│           ├── tasks
│           ├── tests
│           └── vars

続いてtasks配下にymlファイルを作成して行きます。事前チェック、インストール、設定変更、データ投入と4つのステップに分けております。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/tasks/main.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/tasks/main.yml
---
# tasks file for ./roles/

- include_tasks: /home/ansible/websystem/roles/postgres/tasks/check_install.yml
- include_tasks: /home/ansible/websystem/roles/postgres/tasks/install.yml
- include_tasks: /home/ansible/websystem/roles/postgres/tasks/configure.yml
- include_tasks: /home/ansible/websystem/roles/postgres/tasks/data.yml
[ansible@git-server ~]$

事前チェックのymlファイルです。事前チェックと言いつつ、ここではPostgreSQLで使用するポートに対する通信を許可するため、ファイアウォールの設定を有効にしています。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/tasks/check_install.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/tasks/check_install.yml
---
# tasks file for ./roles/postgres

- name: check_install / Allow ports for firewalld
  firewalld:
    port: "{{ item }}"
    permanent: yes
    immediate: yes
    state: enabled
  loop: "{{ postgres_firewalld_port }}"
[ansible@git-server ~]$

続いてインストール用のymlファイルです。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/tasks/install.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/tasks/install.yml
---
# tasks file for ./roles/postgres

#1.Postgresバージョンの指定
- name: install / Designate Postgresql version
  command: dnf module enable postgresql:15 -y
  become: true

#2.Postgresパッケージインストール
- name: install / Install required packages
  yum:
    name: "{{ postgres_packages }}"
    state: present

#3.Postgres拡張モジュールインストール
- name: install / Install additional packages
  yum:
    name: "{{ postgres_contrib_packages }}"
    state: present

#4.psycopg2インストール
- name: install / Install psycopg2
  yum:
    name: "{{ psycopg2_packages }}"
    state: present

#5.DB初期化有無の確認
- name: install / Check if PostgreSQL database is initialized
  stat:
    path: /var/lib/pgsql/data/postgresql.conf
  register: pgdata_dir_file

#6.DB初期化
- name: install / Initialize PostgreSQL database
  command: postgresql-setup --initdb
  when: not pgdata_dir_file.stat.exists
  become: true
[ansible@git-server ~]$

続いて設定変更用のymlファイルです。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/tasks/configure.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/tasks/configure.yml
# tasks file for ./roles/postgres

# 1.postgresql.confの配置
- name: configure / Setup postgresql.conf file
  copy:
    src: postgresql.conf
    dest: /var/lib/pgsql/data/postgresql.conf
    owner: postgres
    group: postgres
    mode: 0600

# 2.pg_hba.confの配置
- name: configure / Setup pg_hba.conf file
  copy:
    src: pg_hba.conf
    dest: /var/lib/pgsql/data/pg_hba.conf
    owner: postgres
    group: postgres
    mode: 0600

# 3.Postgres起動
- name: configure / Start postgres service
  systemd:
    name: postgresql.service
    state: reloaded
    enabled: yes
  become: yes

# 4.Postgres起動確認
- name: configure / Wait for postgres restart
  wait_for:
    port: "{{ postgres_service_port }}"
    delay: 3
    timeout: 60
  become: yes

#5.Postgresユーザへの権限付与
- name: configure / add sudo priviledge to postgres user
  lineinfile:
    dest: /etc/sudoers
    backup: yes
    line: 'postgres ALL=(ALL) NOPASSWD: ALL'

#6.データベース作成
- name: configure / create database
  become_user: postgres
  postgresql_db:
    name: quiz
    encoding: UTF-8

#7.データベース作成用SQLファイル配置
- name: configure / deploy sql file for table creation
  copy:
    src: table.sql
    dest: /var/lib/pgsql/table.sql
    owner: postgres
    group: postgres
    mode: 0600

#8.データベース作成
- name: configure / run query from SQL script
  become_user: postgres
  postgresql_query:
    login_db: quiz
    path_to_script: /var/lib/pgsql/table.sql
    as_single_query: true
    positional_args:
    - 1
[ansible@git-server ~]$

データ投入用のymlファイルを作成します。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/tasks/data.yml
[ansible@git-server ~]$
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/tasks/data.yml
# tasks file for ./roles/postgres

#1.データ登録用SQLファイル配置
- name: configure / deploy sql file for data insert
  copy:
    src: data.sql
    dest: /var/lib/pgsql/data.sql
    owner: postgres
    group: postgres
    mode: 0600

#2.データ登録
- name: configure / run query from SQL script
  become_user: postgres
  postgresql_query:
    login_db: quiz
    path_to_script: /var/lib/pgsql/data.sql
    as_single_query: true
    positional_args:
    - 1
[ansible@git-server ~]$

続いてvars配下にパラメーターを指定したymlファイルを作成します。

[ansible@ip-172-31-81-212 ~]$ vi /home/ansible/websystem/roles/postgres/vars/main.yml
[ansible@ip-172-31-81-212 ~]$ cat /home/ansible/websystem/roles/postgres/vars/main.yml
---
# vars file for /home/ansible/websystem/roles/postgres

postgres_service_port: 5432
postgres_firewalld_port:
  - "{{ postgres_service_port }}/tcp"
postgres_packages:
  - postgresql-server
postgres_contrib_packages:
  - postgresql-contrib
postgresql_data_dir:
  - /var/lib/pgsql/data
postgresql_conf_path:
  - /var/lib/pgsql/data/postgresql.conf
postgres_dbname:
  - quiz
postgres_dbuser:
  - postgres
postgres_dbpass:
  - mL7&%ZV!TSpG

さらにfilesフォルダ配下に必要なファイルを置いてきます。postgresql.conf、pg_hba.confに加えて、SQLを記載したファイルも配置します。まずはテーブル作成のSQLを記載したファイルをサンプルで記載します。ご自身の作りたいアプリに応じて変更してください。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/files/table.sql
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/files/table.sql
create TABLE IF NOT EXISTS users_roles (
    user_id integer NOT NULL,
    role_id integer NOT NULL
);
create TABLE IF NOT EXISTS users (
    userid SERIAL NOT NULL,
    username varchar(255) NOT NULL UNIQUE,
    password varchar(255) NOT NULL,
    primary key (userid)
);
CREATE TABLE IF NOT EXISTS quiz (
    quizid SERIAL NOT NULL,
    userid integer NOT NULL,
    quiz varchar(255),
    category varchar(255),
    option1 varchar(255),
    option2 varchar(255),
    option3 varchar(255),
    option4 varchar(255),
    answer integer,
    explain varchar(1000),
    link varchar(255),
    status varchar(255),
    PRIMARY KEY (quizid)
);
create TABLE IF NOT EXISTS roles (
    roleid SERIAL NOT NULL,
    rolename varchar(255) NOT NULL,
    primary key (roleid)
);
[ansible@git-server ~]$

続いてデータ投入用のSQLを記載したymlファイルとなります。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/postgres/files/data.sql
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/postgres/files/data.sql
INSERT INTO users (username, password)
SELECT 'public', 'password'
WHERE NOT EXISTS (
  SELECT 1 FROM users WHERE username = 'public'
);

DO $$
BEGIN
    -- quizテーブルに1件もなければ処理を実行
    IF NOT EXISTS (SELECT 1 FROM quiz) THEN

        -- シーケンスの初期化(次のINSERTで1から開始する)
        PERFORM setval('quiz_quizid_seq', 1, false);

        -- 1000件のレコードをループで挿入(1ループで5件ずつ)
        FOR i IN 1..1000 LOOP

            -- クイズ1
            INSERT INTO quiz (quizid, userid, quiz, category, option1, option2, option3, option4, answer, explain, status, link)
            VALUES (DEFAULT, i,
                'Oracle GoldenGateのソースノードにて起動しているプロセスは?',
                'Oracle',
                'Manager,Extract(Capture)',
                'Manager,Extract(Capture),Extract(DataPump),Collector',
                'Manager,Extract(Capture),Extract(DataPump)',
                'Extract(Capture),Extract(DataPump)',
                '3',
                'ターゲットノードにて起動しているプロセスは、Manager,Extract(Capture),Extract(DataPump)となります。',
                '未完了',
                'https://eeengineer.com/oracle-golden-gate/');

        END LOOP;
    END IF;
END
$$;
1.4 Tomcatインストール/設定

Tomcatも同じようにymlファイルを作っていきましょう。事前チェック、インストール、設定変更の3つのステップに分けております。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/tomcat/tasks/main.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/tomcat/tasks/main.yml
---
# tasks file for ./roles/

- include_tasks: /home/ansible/websystem/roles/tomcat/tasks/check_install.yml
- include_tasks: /home/ansible/websystem/roles/tomcat/tasks/install.yml
- include_tasks: /home/ansible/websystem/roles/tomcat/tasks/configure.yml
[ansible@git-server ~]$

Tomcatで使うポートに対する通信を有効にします。

[ansible@git-server ~]# vi /home/ansible/websystem/roles/tomcat/tasks/check_install.yml
[ansible@git-server ~]# cat /home/ansible/websystem/roles/tomcat/tasks/check_install.yml
---
# tasks file for ./roles/tomcat

- name: check_install / Allow ports for firewalld
  firewalld:
    port: "{{ item }}"
    permanent: yes
    immediate: yes
    state: enabled
  loop: "{{ tomcat_firewalld_port }}"

[ansible@git-server ~]#

Tomcatインストール用のymlファイルです。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/tomcat/tasks/install.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/tomcat/tasks/install.yml
---
# tasks file for ./roles/tomcat

#1.JDKインストーラのダウンロード
- name: install / Download tomcat installer
  get_url:
    url: https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-x64_bin.tar.gz
    dest: /tmp
    timeout: 60

#2.JDK用ディレクトリ作成
- name: install / Create JDK Directory
  ansible.builtin.file:
    path: /opt/java
    state: directory
    owner: root
    group: root
    mode: '0755'

#3.JDKインストール
- name: install / Install JDK
  unarchive:
    src: /tmp/openjdk-21.0.2_linux-x64_bin.tar.gz
    dest: /opt/java
    remote_src: yes

#4.グループ作成
- name: Add tomcat group
  group:
    name: tomcat
    state: present

#5.ユーザ作成
- name: Add tomcat user
  user:
    name: tomcat
    group: tomcat
    shell: /bin/false
    create_home: no
    state: present

#6.Tomcatインストーラのダウンロード
- name: install / Download tomcat installer
  get_url:
    url: https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.41/bin/apache-tomcat-10.1.41.tar.gz
    dest: /tmp
    timeout: 60

#7.Tomcatインストール
- name: install / Install tomcat
  unarchive:
    src: /tmp/apache-tomcat-10.1.41.tar.gz
    dest: /opt
    remote_src: yes

#8.ディレクトリ存在確認
- file:
    path: /opt/tomcat
    state: absent

#9.ディレクトリのリネーム
- name: install / Rename directory
  command:
    cmd: 'mv -f /opt/apache-tomcat-10.1.41 /opt/tomcat'

#10.権限変更
- name: configure / directory permission change
  file:
   path: /opt/tomcat
   state: directory
   owner: tomcat
   group: tomcat
   recurse: yes

#11.インストーラ削除
- name: install / Delete installer
  file:
    state: absent
    path: /tmp/apache-tomcat-10.1.41.tar.gz
[ansible@git-server ~]$

Tomcat設定用のymlファイルです。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/tomcat/tasks/configure.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/tomcat/tasks/configure.yml
#1.server.xmlの配置
- name: configure / Setup global configuration file
  copy:
    src: server.xml
    dest: /opt/tomcat/conf/server.xml
    owner: root
    group: tomcat
    mode: 0644

#2. context.xml配置
- name: configure / deploy context.xml
  copy:
   src: context.xml
   dest: /opt/tomcat/conf/context.xml
   owner: tomcat
   group: tomcat
   mode: 0600

#3. setenv配置
- name: configure / deploy setenv.sh
  copy:
   src: setenv.sh
   dest: /opt/tomcat/bin/setenv.sh
   owner: tomcat
   group: tomcat
   mode: 0755

#4.ユニットファイルの配置
- name: configure / deploy systemd setting file
  copy:
    src: tomcat.service
    dest: /etc/systemd/system/tomcat.service
    owner: root
    group: root
    mode: 0755

#5.不要ディレクトリ削除1
- name: configure / delete unnecessary folder
  ansible.builtin.file:
    path: /opt/tomcat/webapps/docs
    state: absent

#6.不要ディレクトリ削除2
- name: configure / delete unnecessary folder
  ansible.builtin.file:
    path: /opt/tomcat/webapps/examples
    state: absent

#7.ユニットファイルの読み込み
- name: configure / systemd daemon-reload
  command: /usr/bin/systemctl daemon-reload
  become: yes

#8.Tomcat自動起動設定
- name: configure / systemd enable
  command: /usr/bin/systemctl enable tomcat.service
  become: yes

#9.Tomcat起動
- name: configure / Start tomcat service
  systemd:
    name: tomcat
    state: restarted
    enabled: yes

#10.Tomcat起動確認
- name: configure / Wait for tomcat restart
  wait_for:
    host: "{{ ansible_default_ipv4.address }}"
    port: "{{ tomcat_service_port }}"
    delay: 3
    timeout: 60
[ansible@git-server ~]$
1.5 Apacheインストール/設定

Apacheのインストールと設定をしていきます。Tomcatと同様に、事前チェック、インストール、設定変更の3つのステップに分けております。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/apache/tasks/main.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/apache/tasks/main.yml
---
# tasks file for ./roles/

- include_tasks: /home/ansible/websystem/roles/apache/tasks/check_install.yml
- include_tasks: /home/ansible/websystem/roles/apache/tasks/install.yml
- include_tasks: /home/ansible/websystem/roles/apache/tasks/configure.yml

[ansible@git-server ~]$

Apacheで使うポートに対する通信を有効にします。

[ansible@git-server apache]$ vi /home/ansible/websystem/roles/apache/tasks/check_install.yml
[ansible@git-server apache]$ cat /home/ansible/websystem/roles/apache/tasks/check_install.yml
---
# tasks file for ./roles/tomcat

- name: check_install / Allow ports for firewalld
  firewalld:
    port: "{{ item }}"
    permanent: yes
    immediate: yes
    state: enabled
  loop: "{{ apache_firewalld_port }}"

[ansible@git-server apache]$

続いてインストールです。

[ansible@git-server apache]$ vi /home/ansible/websystem/roles/apache/tasks/install.yml
[ansible@git-server apache]$ cat /home/ansible/websystem/roles/apache/tasks/install.yml
---
# tasks file for ./roles/apache

- name: install / Install required packages
  yum:
    name: "{{ apache_packages }}"
    state: present
[ansible@git-server apache]$

設定変更です。http.confファイルはfilesディレクトリ配下に配置しておいてください。

[ansible@git-server apache]$ vi /home/ansible/websystem/roles/apache/tasks/configure.yml
[ansible@git-server apache]$ cat /home/ansible/websystem/roles/apache/tasks/configure.yml
---
# tasks file for ./roles/apache

#1.httpd.conf配置
- name: configure / Setup global configuration file
  copy:
    src: httpd.conf
    dest: /etc/httpd/httpd.conf
    owner: root
    group: root
    mode: 0644

#2.Apache起動
- name: configure / Start apache service
  systemd:
    name: httpd
    state: reloaded
    enabled: yes

#3.Apache起動確認
- name: configure / Wait for apache restart
  wait_for:
    host: "{{ ansible_default_ipv4.address }}"
    port: "{{ apache_service_port }}"
    delay: 3
    timeout: 60

[ansible@git-server apache]$

変数を設定します。

[ansible@git-server apache]$ vi /home/ansible/websystem/roles/apache/vars/main.yml
[ansible@git-server apache]$ cat /home/ansible/websystem/roles/apache/vars/main.yml
---
# vars file for ./roles/tomcat

apache_service_port: 80
apache_firewalld_port:
  - "{{ apache_service_port }}/tcp"
apache_packages:
  - httpd
[ansible@git-server apache]$
1.6 アプリケーションのデプロイ

最後、アプリケーションのデプロイです。Spring Bootで開発したJavaアプリケーションをデプロイします。configure.ymlのみ作成しています。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/app/tasks/main.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/app/tasks/main.yml
---
# tasks file for ./roles/

- include_tasks: /home/ansible/websystem/roles/app/tasks/configure.yml
[ansible@git-server ~]$

warファイルを配置してTomcatを再起動するymlファイルとなります。

[ansible@git-server ~]$ vi /home/ansible/websystem/roles/app/tasks/configure.yml
[ansible@git-server ~]$ cat /home/ansible/websystem/roles/app/tasks/configure.yml
#1.warファイル配置
- name: configure / Deploy application
  copy:
    src: ROOT.war
    dest: /opt/tomcat/webapps/ROOT.war
    owner: tomcat
    group: tomcat
    mode: 0644

#2.Tomcat再起動
- name: configure / Start tomcat service
  systemd:
    name: tomcat
    state: restarted
    enabled: yes

#3.Tomcat起動確認
- name: configure / Wait for tomcat restart
  wait_for:
    host: "{{ ansible_default_ipv4.address }}"
    port: "{{ tomcat_service_port }}"
    delay: 3
    timeout: 60
[ansible@git-server ~]$

2. GitLab RunnerによるPlaybook適用

2.1 GitLab Runnerジョブ起動用のyml作成

GitLab Runnerでansible-playbookコマンドをジョブ実行するためのymlファイル(.gitlab-ci.yml)を作成します。
scriptの項目にコマンドを記載します。コマンド実行対象を開発向け、本番向けに切り替えるために、inventoryファイルを切り替える形としています。ここでは開発環境向けのコマンドを記載しています。
また、when項目をmanualにすることで、ジョブを手動実行する形にしています。

[ansible@git-server ~]$ vi .gitlab-ci.yml
[ansible@git-server ~]$ cat .gitlab-ci.yml
stages:
  - deploy

deploy_playbook:
  stage: deploy
  tags:
    - ansible
  script:
    - ansible-playbook -i /home/ansible/websystem/inventory/dev_inventory.ini /home/ansible/site.yml
  when: manual

[ansible@git-server ~]$
2.2 GitLab Runnerジョブ起動

GitLabにて資材をcommitするとジョブが登録される仕組みになっていますので、実際にやってみましょう。試しにgitlab-ci.ymlを修正して、リモートリポジトリにpushしてみます。

[ansible@git-server ~]$ vi .gitlab-ci.yml
[ansible@git-server ~]$ git add .
[ansible@git-server ~]$ git commit -m "modify gitlab-ci.yml"
[main e7116d3] modify gitlab-ci.yml
 2 files changed, 103 insertions(+), 103 deletions(-)
[ansible@git-server ~]$ git push -u origin main

(gnome-ssh-askpass:6678): Gtk-WARNING **: 07:56:36.265: cannot open display:
error: unable to read askpass response from '/usr/libexec/openssh/gnome-ssh-askpass'
Username for 'http://192.168.56.101': eeengineer

(gnome-ssh-askpass:6679): Gtk-WARNING **: 07:56:38.645: cannot open display:
error: unable to read askpass response from '/usr/libexec/openssh/gnome-ssh-askpass'
Password for 'http://eeengineer@192.168.56.101':
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 579 bytes | 193.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0), pack-reused 0
To http://192.168.56.101/eeengineer/appserver-ansible.git
   a15b32b..e7116d3  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
[ansible@git-server ~]$

続いてGitLabにWebアクセスしてGitLab Runnerのジョブを実行していきましょう。まずはGitLabにログインします。

対象のプロジェクトを選択します。

下記の通りパイプラインが登録されているはずです。手動実行してみましょう。

StatusがRunningに変わった後、Passedになっていればジョブが正常に終了しています。Jobをクリックすることで実行結果の詳細を確認できます。

正常終了しなかった場合は、下記画面にてエラー内容等を確認してリトライしてみて下さい。

GitLab Runnerによるジョブ起動は以上となります。今回は開発環境に対するジョブ実行の例を記載しましたが、本番環境に対してジョブを実行する場合は、gitlab-ci.ymlのansible-playbookコマンドに指定しているinventoryを本番環境向けに指定して下さい。

まとめ

インフラレイヤにおけるCI/CD導入のハンズオンは、以上で終了となります。
本記事では、必要最低限のマニフェストしか作成しませんでしたが、テスト用のマニフェストを用意したり、環境変更用のマニフェストを作成したりと、今後さまざまなニーズが出てくるかと思います。
最初から完璧な仕組みを構築しようとすると、途中で挫折してしまう可能性もあるため、まずはスモールスタートで始め、段階的に改善していくのが良いでしょう。
ぜひ、皆さんもCI/CDをインフラ運用に取り入れ、作業品質と効率の向上を実感していただければと思います。最後までお読みいただき、ありがとうございました。

参考文献

ランナーの設定 | GitLab
GitLab product documentation.

コメント