【Ansible/インフラ構築自動化】Step3:Postgresインストール/データベース作成

本シリーズではAnsibleを適用してWeb3層システム(Apache/Tomcat/Postgres)を自動構築する方法をご紹介しています。
今回はStep3としてPostgresのインストールおよび基本設定の方法をご紹介しますので、ぜひ参考になさって下さい。


まだAnsibleインストールやOS基本設定が済んでいない方は下記のStep1、Step2の記事を参考にしてみて下さい。
【Ansible/インフラ構築自動化】Step1:Ansibleのインストール方法(AWS EC2/CentOS7)
【Ansible/インフラ構築自動化】Step2:AWS EC2に構築したCentOSの基本設定

1. ymlファイル作成

1.1 ディレクトリ作成

まずはAnsibleユーザでmkdirコマンドを実行し、下記の通りディレクトリを作成して下さい。

[ansible@ip-172-31-81-212 ~]$ tree
.
└── web-system
    └── roles
        ├── postgres
        │   ├── files
        │   ├── tasks
        │   ├── tests
        │   └── vars
1.2 プレイブック作成(main.yml)

次はtasksディレクトリにmain.ymlを作成していきます。各タスクの内容は下記の通りです。
・check_install.yml:インストール前の事前準備
・install.yml:インストール作業
・configure.yml:設定作業

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

- include_tasks: roles/postgres/tasks/check_install.yml
- include_tasks: roles/postgres/tasks/install.yml
- include_tasks: roles/postgres/tasks/configure.yml

[ansible@ip-172-31-81-212 ~]$
1.3 インストール事前設定用yml作成(check_install.yml)

インストールする前の設定確認・変更を行います。下記の通りtasksディレクトリにcheck_install.ymlを作成して下さい。ここではpostgresが使うポートの許可設定を入れています。実際に使用するポート番号(5432)の情報は後ほど/varsディレクトリのファイルに記載しますので、ここでは一旦、下記の通り作成してみて下さい。

[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/postgres/tasks/check_install.yml
[ansible@ip-172-31-81-212 ~]$ cat ./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@ip-172-31-81-212 ~]$
1.4 インストール用yml作成(install.yml)

続いてPostgresのインストールです。tasksディレクトリに配下にinstall.ymlを作成して下さい。各処理の詳細は下記の通りです。

  1. リポジトリインストール
    Postgresのパッケージをインストールするためのリポジトリをyumコマンドでインストールしておきます。インストール対象は後述のvarsディレクトリのファイルに記載します。
  2. Postgresパッケージインストール
    Postgresのバージョン13をyumコマンドでインストールします。こちらもインストール対象は後述のvarsディレクトリのファイルに記載します。
  3. DB初期化有無の確認
    次の項番4でDB初期化を実施しますが、すでに初期化されていた場合はスキップする判定を入れるために、DB初期化が完了しているかどうかのステータスを取得します。いろいろやり方はあると思いますが、ここではpostgresql.confファイルが作られているかどうかを判定しています。
  4. DB初期化
    initdbコマンドを実行してDB初期化作業を行います。whenディレクトを記載して項番3で取得したステータスにより処理を行うかどうかを判定しています。
[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/postgres/tasks/install.yml
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/postgres/tasks/install.yml
---
# tasks file for ./roles/postgres

#1.リポジトリインストール
- name: install / Install repository packages
  yum:
    name: "{{ postgres_repository }}"
    state: present

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

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

4.DB初期化
- name: install / Initialize PostgreSQL database
  command: /usr/pgsql-13/bin/postgresql-13-setup initdb
  when: not pgdata_dir_file.stat.exists
  become: true

1.5 設定変更用yml作成(configure.yml)

続いてPostgresの設定作業です。tasksディレクトリに配下にconfigure.ymlを作成して下さい。各処理の詳細は下記の通りです。

  1. postgresql.confの配置
    Postgresの設定ファイルであるpostgresql.confファイルを置き換える処理を記載しています。インストール先フォルダのdataディレクトリにpostgresユーザ権限でコピーします。postgresql.confファイルは事前に編集してfilesディレクトリに格納しておく必要があるので後述します。
  2. pg_hba.confの配置
    Postgresデータベースへの接続に関する設定ファイルであるpg_hba.confファイルを置き換える処理を記載しています。インストール先フォルダのdataディレクトリにpostgresユーザ権限でコピーします。pg_hba.confファイルは事前に編集してfilesディレクトリに格納しておく必要があるので後述します。
  3. Postgres起動
    systemdコマンドでPostgresを起動しています。Postgres Version13のサービス名であるpostgresql-13.serviceを指定します。
  4. Postgres起動確認
    Postgres起動後のステータスを確認する処理を記載しています。起動に少し時間がかかるので適当なdelay、timoutの時間を指定します。
  5. postgresユーザへの権限付与
    postgresユーザがsudoコマンドでrootユーザに昇格できるようにsudoersファイルに設定を追加しています。
  6. データベース作成
    テスト用にwebsystemというデータベースを作成しています。
  7. ユーザ作成
    アプリからwebsystemデータベースにログインする際に使用するユーザを作成しています。分かりやすくuser名、パスワードともにwebsystemとしています。
  8. テーブル作成
    テスト用のテーブルをcustomerlistという名称で作成しています。id、名前、emailのカラムを作成することでemailリストのようなものを作成します。
  9. テストデータ登録用SQLファイル配置
    項番10でSQLファイルを実行して試験データを登録するため、事前作成したSQLファイルを配置しておきます。postgresユーザから参照できるディレクトリに配置しておいてください。実際に登録したファイルの内容は後述します。
  10. テストデータ登録
    項番9で作成したSQLファイルを実行してテストデータを登録します。
[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/postgres/tasks/configure.yml
[ansible@ip-172-31-81-212 ~]$ cat ./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/13/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/13/data/pg_hba.conf
    owner: postgres
    group: postgres
    mode: 0600

# 3.Postgres起動
- name: configure / Start postgres service
  systemd:
    name: postgresql-13.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: websystem
    encoding: UTF-8

#7.ユーザ作成
- name: configure / create user
  become_user: postgres
  postgresql_user:
    login_db: websystem
    user: websystem
    password: websystem
    priv: ALL
    state: present

#8.テーブル作成
- name: configure / create table
  become_user: postgres
  postgresql_table:
    login_db: websystem
    login_password: websystem
    name: customerlist
    owner: websystem
    columns:
    - id bigserial primary key
    - name text
    - email text

#9.テストデータ登録用SQLファイル配置
- name: configure / deploy sql file
  copy:
    src: customerlist.sql
    dest: /var/lib/pgsql/13/customerlist.sql
    owner: postgres
    group: postgres
    mode: 0600

#10.テストデータ登録
- name: configure / run query from SQL script
  become_user: postgres
  postgresql_query:
    login_db: websystem
    path_to_script: /var/lib/pgsql/13/customerlist.sql
    positional_args:
    - 1




1.6 設定ファイル/SQLファイル作成

1.5で反映するための設定ファイルおよびSQLコマンドファイルを事前に作成します。
まずは要件に応じて修正したpostgresql.confをfilesディレクトリ配下に格納しておいてください。今回はshared_buffersの値をデフォルト値の128MBから512MBに変更しています。

[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/postgres/files/postgresql.conf
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/postgres/files/postgresql.conf |grep shared_buffers
#shared_buffers = 128MB                  # min 128kB
shared_buffers = 512MB                  # min 128kB

続いて要件に応じて修正したpg_hba.confをfilesディレクトリ配下に格納しておいてください。今回はwebsystemデータベースに対する接続設定を追加しています。

[ansible@ip-172-31-81-212 ~]$ vi /home/ansible/websystem/roles/postgres/files/pg_hba.conf
[ansible@ip-172-31-81-212 ~]$ cat /home/ansible/websystem/roles/postgres/files/pg_hba.conf
~下記抜粋~

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
#local   all             all                                     peer
local   postgres        all                                     peer
local   websystem       all                                     trust  ##設定追加
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256

続いてテストデータをINSERTするためのSQLコマンドファイルをfilesディレクトリ配下に格納しておいてください。

[ansible@ip-172-31-81-212 ~]$ vi /home/ansible/websystem/roles/postgres/files/customerlist.sql
[ansible@ip-172-31-81-212 ~]$ cat /home/ansible/websystem/roles/postgres/files/customerlist.sql
insert into public.customerlist values (1,'aaaa','aaaa@gmail.com');
insert into public.customerlist values (2,'bbbb','bbbb@gmail.com');
insert into public.customerlist values (3,'cccc','cccc@gmail.com');

最後に作成したファイルのパーミッションが下記の通りになっているか確認しておいてください。

[ansible@ip-172-31-81-212 ~]$ ls -l /home/ansible/websystem/roles/postgres/files/
total 52
-rw-rw-r--. 1 ansible ansible   204 Feb 24 05:48 customerlist.sql
-rw-rw-r--. 1 ansible ansible  4688 Feb 27 06:18 pg_hba.conf
-rw-rw-r--. 1 ansible ansible 40667 Feb 20 07:06 postgresql.conf

1.7 変数定義

最後に変数を定義しましょう。varsディレクトリ配下にmain.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 ./roles/postgres

postgres_service_port: 5432
postgres_firewalld_port:
  - "{{ postgres_service_port }}/tcp"
postgres_repository:
  - https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
postgres_packages:
  - postgresql13-server
postgres_python_psycopg2:
  - python-psycopg2
postgresql_data_dir:
  - /var/lib/pgsql/13/data
postgresql_conf_path:
  - /var/lib/pgsql/13/data/postgresql.conf
postgres_dbname:
  - websystem
postgres_dbuser:
  - websystem
postgres_dbpass:
  - websystem
[ansible@ip-172-31-81-212 ~]$
1.8 実行対象有効化

最後にpostgresのplaybookが実行されるように、前のStepで作成したwebsystem_install.ymlのrole:postgresに関する記載のコメントアウトを外しておきましょう。

[ansible@ip-172-31-81-212 ~]$ vi /home/ansible/websystem/websystem_install.yml
[ansible@ip-172-31-81-212 ~]$ cat /home/ansible/websystem/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@ip-172-31-81-212 ~]$

2. プレイブック実行

2.1 プレイブック実行

続いてansible-playbookコマンドを実行していきましょう。
心配な人は事前に-vvvvオプションをつけて実行できるか確認してみて下さい。ただし実際に実行しないと確認できない処理もあるのでNGとなる可能性が高いです。

[ansible@ip-172-31-81-212 ~]$ ansible-playbook -i ./websystem/inventory/inventory.ini  ./websystem/websystem_install.yml -t postgres

PLAY [Install for web system] ***********************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [web1i]

TASK [postgres : include_tasks] *********************************************************************************************************************************************
included: /home/ansible/websystem/roles/postgres/tasks/check_install.yml for web1i

TASK [postgres : check_install / Allow ports for firewalld] *****************************************************************************************************************
ok: [web1i] => (item=5432/tcp)

TASK [postgres : include_tasks] *********************************************************************************************************************************************
included: /home/ansible/websystem/roles/postgres/tasks/install.yml for web1i

TASK [postgres : install / Install repository packages] *********************************************************************************************************************
ok: [web1i]

TASK [postgres : install / Install required packages] ***********************************************************************************************************************
ok: [web1i]

TASK [postgres : install / Check if PostgreSQL database is initialized] *****************************************************************************************************
ok: [web1i]

TASK [postgres : install / Initialize PostgreSQL database] ******************************************************************************************************************
changed: [web1i]

TASK [postgres : include_tasks] *********************************************************************************************************************************************
included: /home/ansible/websystem/roles/postgres/tasks/configure.yml for web1i

TASK [configure / Setup postgresql.conf file] *******************************************************************************************************************************
changed: [web1i]

TASK [configure / Start postgres service] ***********************************************************************************************************************************
changed: [web1i]

TASK [configure / Wait for postgres restart] ********************************************************************************************************************************
ok: [web1i]

PLAY RECAP ******************************************************************************************************************************************************************
web1i                      : ok=12   changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0




ok, changedになっていたら成功です。

2.1 プレイブック実行結果確認

プレイブック実行によってPostgresが適切に設定されているか確認しましょう。

1,. Postgresの起動確認
systemdコマンドで状態確認しましょう。Activeの項目がactive (running)になっていれば正常に起動できています。

[ansible@ip-172-31-81-212 ~]$ sudo systemctl status postgresql-13
● postgresql-13.service - PostgreSQL 13 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2024-02-23 06:39:22 JST; 1min 11s ago
     Docs: https://www.postgresql.org/docs/13/static/
  Process: 7950 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 11860 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 11865 (postmaster)
   CGroup: /system.slice/postgresql-13.service
           ├─11865 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
           ├─11867 postgres: logger
           ├─11869 postgres: checkpointer
           ├─11870 postgres: background writer
           ├─11871 postgres: walwriter
           ├─11872 postgres: autovacuum launcher
           ├─11873 postgres: stats collector
           └─11874 postgres: logical replication launcher

Feb 23 06:39:21 ip-172-31-81-212.ec2.internal systemd[1]: Starting PostgreSQL 13 database server...
Feb 23 06:39:22 ip-172-31-81-212.ec2.internal postmaster[11865]: 2024-02-23 06:39:22.041 JST [11865] LOG:  redirecting log output to logging collector process
Feb 23 06:39:22 ip-172-31-81-212.ec2.internal postmaster[11865]: 2024-02-23 06:39:22.041 JST [11865] HINT:  Future log output will appear in directory "log".
Feb 23 06:39:22 ip-172-31-81-212.ec2.internal systemd[1]: Started PostgreSQL 13 database server.
[ansible@ip-172-31-81-212 ~]$


2. Postgresが使用しているポート確認
lsof コマンドでPostgresが使用しているポートが5432であることを確認しましょう。

[ansible@ip-172-31-81-212 ~]$ sudo lsof -i:5432
COMMAND     PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
postmaste 11865 postgres    6u  IPv4  68786      0t0  TCP localhost:postgres (LISTEN)
[ansible@ip-172-31-81-212 ~]$



3. Postgresの設定ファイル確認
catコマンドでPostgresの設定ファイルが想定通り編集されているか確認しましょう。

[ansible@ip-172-31-81-212 ~]$ sudo cat /var/lib/pgsql/13/data/postgresql.conf | grep shared_buffers
#shared_buffers = 128MB                  # min 128kB
shared_buffers = 512MB                  # min 128kB
[ansible@ip-172-31-81-212 ~]$ sudo cat /home/ansible/websystem/roles/postgres/files/pg_hba.conf
~下記抜粋~

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
#local   all             all                                     peer
local   postgres        all                                     peer
local   websystem       all                                     trust  ##設定追加
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256

4. データベース接続
postgresユーザにスイッチし、psqlコマンドでwebsystemデータベースに接続できることを確認してください。また、データベース一覧を表示させて想定通りにデータベースが作成できていることを確認してください。

[ansible@ip-172-31-81-212 ~]$ sudo su - postgres
Last login: Sun Feb 25 07:19:45 JST 2024 on pts/0
-bash-4.2$ psql -U websystem
psql (13.14)
Type "help" for help.

websystem=> 
websystem=> \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+------------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres           +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres           +
           |          |          |             |             | postgres=CTc/postgres
 websystem | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres          +
           |          |          |             |             | postgres=CTc/postgres +
           |          |          |             |             | websystem=CTc/postgres
(4 rows)

4. テストデータ確認
websystemテーブルにテストデータが適切にインポートされているかどうかを確認してください。

websystem=> select * from customerlist;
 id | name |     email
----+------+----------------
  1 | aaaa | aaaa@gmail.com
  2 | bbbb | bbbb@gmail.com
  3 | cccc | cccc@gmail.com
(3 rows)




上記の通りテストデータが参照できたら成功です!

まとめ

 Step3ではPostgresのインストール、各種設定、データベース/テーブル作成、テストデータ登録まですべてAnsibleで自動構築する方法を御紹介してきました。なかなか一回でansible-playbookコマンドが成功することはないかと思いますが、トライ&エラーを繰り返して1つずつエラーを解消する過程で理解が深まりますので、ぜひあきらめずに最後まで試してみていただければと思います。
 続いてStep4ではTomcatのインストールおよび設定を紹介していきますので引き続き参照いただけると幸いです。

参考文献

Ansible実践ガイド

Qiita:ansibleでpostgresqlインストール

Shinta’s website:Tomcat と PostgreSQL で Web アプリケーションを! (Servlet/JSP)

コメント