【初心者向けハンズオン】インフラ構築自動化 ~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/インフラ構築自動化】Step4:Tomcatのインストール・Postgres連携

    参考文献

    Ansible実践ガイド

    Qiita:ansibleでpostgresqlインストール

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

    コメント