【Ansible/インフラ構築自動化】Step4:Tomcatのインストール・Postgres連携

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


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

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

1. ymlファイル作成

1.1 ディレクトリ作成

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

[ansible@ip-172-31-81-212 ~]$ tree
.
└── websystem
    └── roles
        ├── tomcat
        │   ├── 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/tomcat/tasks/main.yml
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/tasks/main.yml
---
# tasks file for ./roles/

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

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

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

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

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

  1. OpenJDKインストール
    Tomcatを動作させるためにはOpenJDKをインストールする必要がありますのでyumコマンドでインストールします。今回はOpenJDKのバージョン11をインストールしています。
  2. openjdk-develインストール
    javaの開発環境ツールも合わせてインストールしておきます。後続の動作確認にてjavacコマンドを使用してclassファイルを作成する際に使用します。
  3. ユーザ作成
    tomcatユーザを作成します。
  4. Tomcatインストーラのダウンロード
    yumコマンドだとサポート切れの古いバージョンしかインストールできないので、公式インストーラをダウンロードしてインストールしていきます。今回はTomcatバージョン9をインストールします。
  5. Tomcatインストール
    ダウンロードしたインストーラを/etcディレクトリに展開します。
  6. ディレクトリ存在確認
    /etc/tomcatディレクトリの存在確認をしています。/etc/tomcatディレクトリが存在していた場合に7.のmvコマンドを実行すると、期待している結果と異なる結果となってしまいますのでご注意ください。
  7. ディレクトリのリネーム
    好みの問題ですが、5.で展開したままののディレクトリのままだと扱いづらいので、/etc/tomcatディレクトリに名称を変更しています。
  8. 権限変更
    /etc/tomcat配下のディレクトリの権限を変更して、tomcatユーザで参照、実行できるように変更します。
  9. インストーラ削除
    最後に後片付けとして、ダウンロードしたインストーラを削除しておきます。
[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/tomcat/tasks/install.yml
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/tasks/install.yml
---
# tasks file for ./roles/tomcat

#1.OpenJDKインストール
- name: install / Install openjdk packages
  yum:
    name: "{{ openjdk_packages }}"
    state: present

#2.openjdk-develインストール
- name: install / Install openjdk-devel packages
  yum:
    name: "{{ openjdkdevel_packages }}"
    state: present

#3.ユーザ作成
- name: install / Add tomcat user
  user:
    name: tomcat
    group: tomcat
    system: yes

#4.Tomcatインストーラのダウンロード
- name: install / Download tomcat installer
  get_url:
    url: http://ftp.jaist.ac.jp/pub/apache/tomcat/tomcat-9/v9.0.85/bin/apache-tomcat-9.0.85.tar.gz
    dest: /tmp
    timeout: 60

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

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

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

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

#9.インストーラ削除
- name: install / Delete installer
  file:
    state: absent
    path: /tmp/apache-tomcat-9.0.85.tar.gz
1.5 設定変更用yml作成(configure.yml)

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

  1. server.xmlの配置
    Tomcatの設定ファイルであるserver.xmlファイルを置き換える処理を記載しています。インストール先フォルダのconfディレクトリにrootオーナ、tomcatグループ権限でコピーします。server.xmlファイルは事前に編集してfilesディレクトリに格納しておく必要があるので後述します。
  2. JDBCドライバのダウンロード
    curlコマンドでpostgresql用のJDBCドライバをダウンロードします。Ansibleのhomeディレクト直下にファイルが置かれます。
  3. JDBCドライバ権限変更
    アプリ実行時に読み込みできるように適切な権限に変更します。
  4. テストアプリ配置用のディレクトリ作成
    テスト用アプリを配置するディレクトリを作成します。今回は/etc/tomcat/webapps配下にtestjspというディレクトリを作成しています。
  5. テストアプリ配置
    テスト用に作成したjspファイルを配置します。
  6. context.xml配置
    Postgresqlに接続するための設定を記載したcontext.xmlを配置します。
  7. ユニットファイルの配置
    Tomcatをsystemdコマンドで起動・停止するためのユニットファイルを配置します。
  8. ユニットファイルの読み込み
    8.で配置したユニットファイルをsystemctl daemon-reloadコマンドで認識させます。
  9. Tomcat自動起動設定
    systemctl enable tomcat.serviceコマンドを実行して自動起動設定を有効にします。
  10. Tomcat起動
    systemdコマンドでTomcatを起動しています。
  11. Tomcat起動確認
    Tomcat起動後のステータスを確認する処理を記載しています。起動に少し時間がかかるので適当なdelay、timoutの時間を指定します。
#1.server.xmlの配置
- name: configure / Setup global configuration file
  copy:
    src: server.xml
    dest: /etc/tomcat/conf/server.xml
    owner: root
    group: tomcat
    mode: 0644

#2.JDBCドライバのダウンロード
- name: configure / download jdbc driver
  get_url:
   dest: /etc/tomcat/lib/
   url: https://jdbc.postgresql.org/download/postgresql-42.3.4.jar

#3.JDBCドライバ権限変更
- name: change permission
  file:
   path: /etc/tomcat/lib/postgresql-42.3.4.jar
   state: file
   owner: tomcat
   group: tomcat
   mode: 0640

#4. テストアプリ配置用のディレクトリ作成
- name: configure / directory creation
  file:
   path: "/etc/tomcat/webapps/testjsp"
   state: directory
   owner: tomcat
   group: tomcat
   mode: 0750

#5. テストアプリ配置
- name: configure / deploy jsp file
  copy:
   src: test.jsp
   dest: /etc/tomcat/webapps/testjsp
   owner: tomcat
   group: tomcat
   mode: 0750

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

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

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

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

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

#11.Tomcat起動確認
- name: configure / Wait for tomcat restart
  wait_for:
    host: "{{ ansible_default_ipv4.address }}"
    port: "{{ tomcat_service_port }}"
    delay: 3
    timeout: 60



1.6 設定ファイル作成

1.5で反映するための設定ファイルおよびユニットを事前に作成します。まずは要件に応じて修正したserver.xmlをfilesディレクトリ配下に格納しておいてください。今回はApahce連動させるためにAJPコネクタを有効にしています。

[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/tomcat/files/server.xml
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/files/server.xml
~抜粋~

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <Connector protocol="AJP/1.3"
               address="0.0.0.0"
               port="8009"
               redirectPort="8443"
               secretRequired="false" />

続いて環境変数を設定するため設定ファイル、/etc/profileを配置してください。

[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/tomcat/files/profile
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/files/profile
# /etc/profile

~省略~

JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.22.0.7-1.el7_9.x86_64
CATALINA_HOME=/etc/tomcat
CLASSPATH=$CATALINA_HOME/lib/postgresql-42.3.4.jar
export JAVA_HOME CATALINA_HOME CLASSPATH

続いてテスト用アプリを格納します。Postgresに接続してテーブルの情報を参照するアプリとなります。

[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/files/test.jsp
<!DOCTYPE html>
<html>
    <head>
        <title>test.jsp</title>
    </head>
    <body>
     <p><font size="7" color="#00ff00">JDBC Connection Test</font></p>
    </body>
</html>

<%@page import="javax.sql.DataSource"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.*" %>
<%@page import="javax.naming.InitialContext"%>
<%@page contentType="text/html" pageEncoding="UTF-8" session="false" %>
<%
        //jndi
        String jndi = "java:comp/env/jdbc/PostgreSQL";
        InitialContext context = null;
        Connection connection = null;
        Statement stmt = null;

        //
        try {
                context = new InitialContext();
                DataSource ds = (DataSource) context.lookup(jndi);
                connection = ds.getConnection();
                String sql = "SELECT * FROM customerlist order by id limit 3000;";
                PreparedStatement pstmt = connection.prepareStatement(sql);
                ResultSet result = pstmt.executeQuery();
                while ( result.next() ) {
                    //
                    int id = result.getInt("id");
                    String name =result.getString("name");
                    String email =result.getString("email");
                    out.println("<p>");
                    out.println("id:" + id + ",name:" + name + ",email:"+ email );
                    out.println("</p>");
                 }
        }
        finally {
                if (context != null) {
                        try {
                                context.close();
                        }
                        catch (Exception e) {
                        }
                }
                if (connection != null) {
                        try {
                                connection.close();
                        }
                        catch (Exception e) {
                        }
                }
        }
%>

続いてPostgresに接続するための設定を記載したcontext.xmlを格納します。

[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/files/context.xml
<?xml version="1.0" encoding="UTF-8"?>
~省略~

#下記を追記
    <!-- PostgreSQL -->
    <Resource name="jdbc/PostgreSQL"
      auth="Container"
      type="javax.sql.DataSource"
      factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
      initialSize="2" maxActive="4" minIdle="1" maxIdle="2"
      username="websystem" password="websystem"
      driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/websystem"
      validationQuery="SELECT 1" />

</Context>

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

[root@ip-172-31-81-212 ~]# ll /home/ansible/websystem/roles/tomcat/files/
total 24
-rw-r--r--. 1 ansible ansible 1834 Mar  2 16:21 context.xml
-rw-rw-r--. 1 ansible ansible 6743 Feb 17 19:21 server.xml
-rw-rw-r--. 1 ansible ansible 1931 Mar  2 16:24 test.jsp
-rw-rw-r--. 1 ansible ansible  336 Feb 18 08:08 tomcat.service

1.7 変数定義

続いて変数を定義しましょう。varsディレクトリ配下にmain.ymlを作成して変数に具体的な値を入れます。

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

tomcat_service_port: 8080
tomcat_firewalld_port:
  - "{{ tomcat_service_port }}/tcp"
openjdk_packages:
  - java-11-openjdk.x86_64
openjdkdevel_packages:
  - java-11-openjdk-devel.x86_64
1.8 実行対象有効化

最後にTomcatの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コマンドを実行していきましょう。NGだった場合には-vvvvオプションをつけてエラー内容を確認して修正してみて下さい。

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

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

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

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

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

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

TASK [tomcat : install / Install openjdk packages] **************************************************************************************************************************
ok: [web1i]

TASK [tomcat : install / Install openjdk-devel packages] ********************************************************************************************************************
ok: [web1i]

TASK [install / Add tomcat user] ********************************************************************************************************************************************
ok: [web1i]

TASK [install / Download tomcat installer] **********************************************************************************************************************************
changed: [web1i]

TASK [install / Install tomcat] *********************************************************************************************************************************************
changed: [web1i]

TASK [tomcat : file] ********************************************************************************************************************************************************
changed: [web1i]

TASK [tomcat : install / Rename directory] **********************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / directory creation] ******************************************************************************************************************************
changed: [web1i]

TASK [tomcat : install / Delete installer] **********************************************************************************************************************************
changed: [web1i]

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

TASK [configure / Setup tomcat configuration file] **************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / download jdbc driver] ****************************************************************************************************************************
changed: [web1i]

TASK [tomcat : change permission] *******************************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / directory creation] ******************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / deploy jsp file] *********************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / deploy context.xml] ******************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / deploy systemd setting file] *********************************************************************************************************************
ok: [web1i]

TASK [tomcat : configure / systemd daemon-reload] ***************************************************************************************************************************
changed: [web1i]

TASK [tomcat : configure / systemd enable] **********************************************************************************************************************************
changed: [web1i]

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

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

PLAY RECAP ******************************************************************************************************************************************************************
web1i                      : ok=25   changed=15   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0





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

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

プレイブック実行によってTomcatが適切にインストールおよび設定されているか確認しましょう。

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

[ansible@ip-172-31-81-212 ~]$ sudo systemctl status tomcat
● tomcat.service - Apache Tomcat 9
   Loaded: loaded (/etc/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (exited) since Sun 2024-03-03 06:04:48 JST; 8min ago
  Process: 9077 ExecStart=/etc/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 9077 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/tomcat.service
           └─9091 /usr/bin/java -Djava.util.logging.config.file=/etc/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djd...

Mar 03 06:04:48 ip-172-31-81-212.ec2.internal systemd[1]: Starting Apache Tomcat 9...
Mar 03 06:04:48 ip-172-31-81-212.ec2.internal systemd[1]: Started Apache Tomcat 9.


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

[ansible@ip-172-31-81-212 ~]$ sudo lsof -i:8080
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    9091 tomcat   44u  IPv4  59214      0t0  TCP *:webcache (LISTEN)


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

[ansible@ip-172-31-81-212 ~]$ vi ./websystem/roles/tomcat/files/server.xml
[ansible@ip-172-31-81-212 ~]$ cat ./websystem/roles/tomcat/files/server.xml
~抜粋~

    <!-- Define an AJP 1.3 Connector on port 8009 -->

    <Connector protocol="AJP/1.3"
               address="0.0.0.0"
               port="8009"
               redirectPort="8443"
               secretRequired="false" />

4. Tomcat管理コンソール接続
Tomcatの管理コンソール画面にアクセスできるか確認します。EC2インスタンスのInboundルールにポート8080を追加して、ブラウザからアクセスできたら成功です。
アクセス先:http://{サーバホスト名}:8080


Inboundルール追加の詳細については下記サイトを参照ください。
※セキュリティの観点から、ひととおり構築が終わったら本管理コンソールは外部から接続できないようしておくことを推奨します。

5. テストアプリ動作確認
では最後にテストアプリが動作するか確認しましょう。ポート指定8080番ポートを指定してTomcat上のテストアプリにアクセスします。
下記の通りテストデータが表示できたら成功です!
アクセス先:http://{サーバホスト名}/testjsp/test.jsp

まとめ

Step4ではTomcatのインストール、各種設定、Tomcat/Postgres連携まですべてAnsibleで自動構築する方法をご紹介しまいした。次のStep5ではApacheインストールおよびApache/Tomcat連携の方法をご紹介します。いよいよ次が最後のStepとなりますので、最後まで見てもらえると嬉しいです!!

参考文献

Ansible実践ガイド

Quiita:Tomcat・PostgreSQL連携

コメント