[AWS CDK] Apache HTTP ServerとApache TomcatのVirtual Hostが動作しているEC2インスタンスをAuto ScalingさせてALBで接続できる環境を一撃で用意する

シェルスクリプトで頑張ればなんとかできます
2023.08.23

一撃でApache HTTP ServerとApache TomcatのVirtual Hostが動作しているEC2インスタンスをAuto ScalingさせてALBで接続したい

こんにちは、のんピ(@non____97)です。

皆さんは一撃でApache HTTP ServerとApache TomcatのVirtual Hostが動作しているEC2インスタンスをAuto ScalingさせてALBで接続したいなと思ったことはありますか? 私はあります。

普通にこのような構成を作成するような場合、ざっくり以下ステップが必要かと思います。

  1. VPCやサブネットなどネットワーク周りのリソースの作成
  2. テンプレート用のEC2インスタンスの作成
  3. テンプレート用のEC2インスタンスでApache HTTP ServerとApache Tomcatを設定
  4. テンプレート用のEC2インスタンスのAMIを取得
  5. 起動テンプレートとAuto Scaling Groupの作成
  6. ALBとターゲットグループの作成
  7. Route 53 Public Hosted ZoneにALBのエイリアスレコードを作成

唐突に検証がしたくなった場合に都度上述の作業を行うのは非常に面倒です。

AWS CDKで頑張って一撃で環境を構築できるようにしてみました。

構成

構成は以下の通りです。

ALBで各ホストへのアクセス数を確認したい場合はホストごとでターゲットグループを分割すると良いかもしれない検証環境構成図

Apache HTTP ServerのVirtual Hostでhoge.web.non-97.netfuga.web.non-97.netを稼働させています。

AWS CDKのコードは以下リポジトリに保存しています。

やっていること

ALBやAuto Scaling Group周りはシンプルです。

L2 Constructで良きように起動テンプレートAuto Scaling Group、ALBを作ってもらいます。取り敢えず最低限必要そうな設定をしています。

./lib/constructs/auto-scaling-group.ts

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as fs from "fs";
import * as path from "path";

export interface AutoScalingGroupProps {
  vpc: cdk.aws_ec2.IVpc;
}

export class AutoScalingGroup extends Construct {
  readonly asg: cdk.aws_autoscaling.AutoScalingGroup;

  constructor(scope: Construct, id: string, props: AutoScalingGroupProps) {
    super(scope, id);

    // Key pair
    const keyName = "test-key-pair";
    const keyPair = new cdk.aws_ec2.CfnKeyPair(this, "KeyPair", {
      keyName,
    });
    keyPair.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);

    // User data
    const userDataScript = fs.readFileSync(
      path.join(__dirname, "../ec2/user-data.sh"),
      "utf8"
    );
    const userData = cdk.aws_ec2.UserData.forLinux({
      shebang: "#!/bin/bash",
    });
    userData.addCommands(userDataScript);

    this.asg = new cdk.aws_autoscaling.AutoScalingGroup(this, "Asg", {
      machineImage: cdk.aws_ec2.MachineImage.lookup({
        name: "RHEL-9.2.0_HVM-20230726-x86_64-61-Hourly2-GP2",
        owners: ["309956199498"],
      }),
      instanceType: new cdk.aws_ec2.InstanceType("t3.micro"),
      blockDevices: [
        {
          deviceName: "/dev/sda1",
          volume: cdk.aws_autoscaling.BlockDeviceVolume.ebs(10, {
            volumeType: cdk.aws_autoscaling.EbsDeviceVolumeType.GP3,
            encrypted: true,
          }),
        },
      ],
      vpc: props.vpc,
      vpcSubnets: props.vpc.selectSubnets({
        subnetGroupName: "Public",
      }),
      keyName,
      maxCapacity: 3,
      minCapacity: 2,
      ssmSessionPermissions: true,
      userData,
      healthCheck: cdk.aws_autoscaling.HealthCheck.elb({
        grace: cdk.Duration.minutes(10),
      }),
    });
    this.asg.scaleOnCpuUtilization("CpuScaling", {
      targetUtilizationPercent: 50,
    });

    // Output
    // Key pair
    new cdk.CfnOutput(this, "GetSecretKeyCommand", {
      value: `aws ssm get-parameter --name /ec2/keypair/${keyPair.getAtt(
        "KeyPairId"
      )} --region ${
        cdk.Stack.of(this).region
      } --with-decryption --query Parameter.Value --output text > ./key-pair/${keyName}.pem`,
    });
  }
}

./lib/constructs/alb.ts

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";

export interface AlbProps {
  vpc: cdk.aws_ec2.IVpc;
  asg: cdk.aws_autoscaling.AutoScalingGroup;
}

export class Alb extends Construct {
  readonly alb: cdk.aws_elasticloadbalancingv2.IApplicationLoadBalancer;

  constructor(scope: Construct, id: string, props: AlbProps) {
    super(scope, id);

    this.alb = new cdk.aws_elasticloadbalancingv2.ApplicationLoadBalancer(
      this,
      "Default",
      {
        vpc: props.vpc,
        internetFacing: true,
        vpcSubnets: {
          subnets: props.vpc.publicSubnets,
        },
      }
    );
    props.asg.connections.allowFrom(this.alb, cdk.aws_ec2.Port.tcp(80));

    const targetGroup =
      new cdk.aws_elasticloadbalancingv2.ApplicationTargetGroup(
        this,
        "TargetGroup",
        {
          vpc: props.vpc,
          port: 80,
          targetType: cdk.aws_elasticloadbalancingv2.TargetType.INSTANCE,
          targets: [props.asg],
        }
      );

    this.alb.addListener("Listener", {
      port: 80,
      protocol: cdk.aws_elasticloadbalancingv2.ApplicationProtocol.HTTP,
      defaultTargetGroups: [targetGroup],
    });
  }
}

OS内の設定はユーザーデータで諸々頑張ります。

行っている処理は以下です。

  1. SSMエージェントとOpenJDK、httpdのインストール
  2. Apache Tomcatのインストール
  3. Apache Tomcat用のユーザーの作成
  4. setenv.shの作成
  5. AJPの設定
  6. Apache TomcatのVirtual Hostの設定
  7. Apache Tomcatのコンテンツの準備
  8. Apache Tomcatのsystemdユニットファイルの作成
  9. Apache Tomcatの起動
  10. httpdのインストール
  11. httpdのVirtual Hostの設定
  12. httpdのコンテンツの準備
  13. httpdの起動
  14. httpdとApache Tomcat間をAJPで通信できるようにSELinuxを修正

実際のユーザーデータは以下の通りです。

./lib/web-stack.ts

#!/bin/bash

# -x to display the command to be executed
set -xe

# Redirect /var/log/user-data.log and /dev/console
exec > >(tee /var/log/user-data.log | logger -t user-data -s 2>/dev/console) 2>&1

# Install Packages
token=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
region_name=$(curl -H "X-aws-ec2-metadata-token: $token" -v http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')

dnf install -y "https://s3.${region_name}.amazonaws.com/amazon-ssm-${region_name}/latest/linux_amd64/amazon-ssm-agent.rpm" java-17-openjdk httpd

# SSM Agent
systemctl enable amazon-ssm-agent
systemctl start amazon-ssm-agent

# Tomcat 10
# Install
cd /usr/local/
curl https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.12/bin/apache-tomcat-10.1.12.tar.gz -o apache-tomcat-10.1.12.tar.gz
tar zxvf apache-tomcat-10.1.12.tar.gz
rm -rf apache-tomcat-10.1.12.tar.gz

# symbolic link
ln -s apache-tomcat-10.1.12 tomcat10
ls -l | grep tomcat

# Add tomcat user
useradd tomcat -M -s /sbin/nologin
id tomcat

mkdir -p ./tomcat10/pid/
chown tomcat:tomcat -R ./tomcat10/
ls -l | grep tomcat
ls -l ./tomcat10/

# setenv.sh
tee ./tomcat10/bin/setenv.sh << 'EOF'
export CATALINA_OPTS=" \
  -server \
  -Xms512m \
  -Xmx512m \
  -Xss512k \
  -XX:MetaspaceSize=512m \
  -Djava.security.egd=file:/dev/urandom"
export CATALINA_PID=/usr/local/tomcat10/pid/tomcat10.pid
EOF

# AJP
line_num_comment_start=$(($(grep -n '<Connector protocol="AJP/1.3"' ./tomcat10/conf/server.xml | cut -d : -f 1)-1))
line_num_comment_end=$(tail -n +$(($line_num_comment_start)) ./tomcat10/conf/server.xml \
  | grep -n '\-\->' \
  | head -n 1 \
  | cut -d : -f 1
)
line_num_comment_end=$(($line_num_comment_end+$line_num_comment_start-1))

sed "${line_num_comment_start}d" ./tomcat10/conf/server.xml > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml
sed "$((${line_num_comment_end}-1))d" ./tomcat10/conf/server.xml > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml
sed "$((${line_num_comment_end}-3))a \               secretRequired=\"false\"" ./tomcat10/conf/server.xml > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml

# Virtual Host
line_num_engine_end=$(($(grep -n '</Engine>' ./tomcat10/conf/server.xml | cut -d : -f 1)))
insert_text=$(cat <<'EOF'

     <Host name="hoge.web.non-97.net" appBase="hoge"
          unpackWARs="true" autoDeploy="false" >
          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="hoge_access_log" suffix=".log" rotatable="false"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
     </Host>

     <Host name="fuga.web.non-97.net" appBase="fuga"
          unpackWARs="true" autoDeploy="false" >
          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="fuga_access_log" suffix=".log" rotatable="false"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
     </Host>
EOF
)
awk -v n=$line_num_engine_end \
  -v s="$insert_text" \
    'NR == n {print s} {print}' ./tomcat10/conf/server.xml \
  > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml

# Contents
line_num_comment_start=$(($(grep -n 'org.apache.catalina.valves.RemoteAddrValve' ./tomcat10/webapps/examples/META-INF/context.xml | cut -d : -f 1)-1))
line_num_comment_end=$(($line_num_comment_start+3))

sed "$((${line_num_comment_start}))a <\!\-\-" ./tomcat10/webapps/examples/META-INF/context.xml > tmpfile && mv -f tmpfile ./tomcat10/webapps/examples/META-INF/context.xml
sed "$((${line_num_comment_end}))a \-\->" ./tomcat10/webapps/examples/META-INF/context.xml > tmpfile && mv -f tmpfile ./tomcat10/webapps/examples/META-INF/context.xml

cp -pr ./tomcat10/webapps/ ./tomcat10/hoge
cp -pr ./tomcat10/webapps/ ./tomcat10/fuga

echo "hoge tomcat $(uname -n)" > ./tomcat10/hoge/examples/index.html
echo "fuga tomcat $(uname -n)" > ./tomcat10/fuga/examples/index.html

# systemd
tee /etc/systemd/system/tomcat10.service << EOF
[Unit]
Description=Apache Tomcat Web Application Container
ConditionPathExists=/usr/local/tomcat10
After=syslog.target network.target

[Service]
User=tomcat
Group=tomcat
Type=oneshot
RemainAfterExit=yes

ExecStart=/usr/local/tomcat10/bin/startup.sh
ExecStop=/usr/local/tomcat10/bin/shutdown.sh

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl list-unit-files --type=service | grep tomcat

systemctl start tomcat10
systemctl enable tomcat10

# httpd
# Virtual Host
tee /etc/httpd/conf.d/httpd-vhosts.conf << EOF
<VirtualHost *:80>
    ServerName hoge.web.non-97.net
    DocumentRoot /var/www/html/hoge

    ProxyPass /tomcat10/ ajp://localhost:8009/
    ProxyPassReverse /tomcat10/ ajp://localhost:8009/

    <Directory /var/www/html/hoge>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/hoge_error_log
    CustomLog /var/log/httpd/hoge_access_log combined
</VirtualHost>

<VirtualHost *:80>
    ServerName fuga.web.non-97.net
    DocumentRoot /var/www/html/fuga

    ProxyPass /tomcat10/ ajp://localhost:8009/
    ProxyPassReverse /tomcat10/ ajp://localhost:8009/

    <Directory /var/www/html/fuga>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/fuga_error_log
    CustomLog /var/log/httpd/fuga_access_log combined
</VirtualHost>
EOF

# Contents
mkdir -p /var/www/html/hoge
mkdir -p /var/www/html/fuga

echo "hoge $(uname -n)" > /var/www/html/hoge/index.html
echo "fuga $(uname -n)" > /var/www/html/fuga/index.html

systemctl start httpd
systemctl enable httpd

# SELinux
setsebool -P httpd_can_network_connect=true
getsebool -a

ポイントをいくつか紹介します。

まず、SSM Agentのインストールです。

デフォルトではRHELにはSSM Agentがインストールされていません。以下AWS公式ドキュメントに記載のインストールスクリプトを参考にインストールします。

sudo yum install -y https://s3.region.amazonaws.com/amazon-ssm-region/latest/linux_amd64/amazon-ssm-agent.rpm

リージョン名の取得はインスタンスメタデータを使います。その際はIMDSv2を意識して取得するようにしています。

# Install Packages
token=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
region_name=$(curl -H "X-aws-ec2-metadata-token: $token" -v http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')

dnf install -y "https://s3.${region_name}.amazonaws.com/amazon-ssm-${region_name}/latest/linux_amd64/amazon-ssm-agent.rpm" java-17-openjdk httpd

AJPコネクターの設定もsedで頑張りました。

デフォルトは以下のようにコメントアウトされています。

/usr/local/tomcat10/conf/server.xml

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!-- 
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443"
               maxParameterCount="1000"
               secretRequired="false"
               />
   -->

どうしてもスクリプトで対応したかったので、<Connector protocol="AJP/1.3"という文字列にマッチした行の1行上と、マッチした行から最初にマッチした-->の行を削除するようにしています。

また、localhostに転送する & address="::1"なのであればシークレットはなくても良いかなと思い、secretRequired="false"をsedで追加しています。

line_num_comment_start=$(($(grep -n '<Connector protocol="AJP/1.3"' ./tomcat10/conf/server.xml | cut -d : -f 1)-1))
line_num_comment_end=$(tail -n +$(($line_num_comment_start)) ./tomcat10/conf/server.xml \
  | grep -n '\-\->' \
  | head -n 1 \
  | cut -d : -f 1
)
line_num_comment_end=$(($line_num_comment_end+$line_num_comment_start-1))

sed "${line_num_comment_start}d" ./tomcat10/conf/server.xml > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml
sed "$((${line_num_comment_end}-1))d" ./tomcat10/conf/server.xml > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml
sed "$((${line_num_comment_end}-3))a \               secretRequired=\"false\"" ./tomcat10/conf/server.xml > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml

シークレットの指定もsecretRequired="false"の追加もしない場合、以下のように怒られます。

22-Aug-2023 01:43:10.596 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
22-Aug-2023 01:43:10.611 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to start component [Connector["ajp-nio-0:0:0:0:0:0:0:1-8009"]]
        org.apache.catalina.LifecycleException: Protocol handler start failed
                at org.apache.catalina.connector.Connector.startInternal(Connector.java:1046)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
                at org.apache.catalina.core.StandardService.startInternal(StandardService.java:445)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
                at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:918)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
                at org.apache.catalina.startup.Catalina.start(Catalina.java:795)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
                at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.base/java.lang.reflect.Method.invoke(Method.java:568)
                at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347)
                at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478)
        Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
                at org.apache.coyote.ajp.AbstractAjpProtocol.start(AbstractAjpProtocol.java:271)
                at org.apache.catalina.connector.Connector.startInternal(Connector.java:1043)
                ... 12 more

Virtual HostについてもAJPコネクターの応用です。</Engine>の1行上にVirtual Hostの記述をawkで追記しました。

line_num_engine_end=$(($(grep -n '</Engine>' ./tomcat10/conf/server.xml | cut -d : -f 1)))
insert_text=$(cat <<'EOF'

     <Host name="hoge.web.non-97.net" appBase="hoge"
          unpackWARs="true" autoDeploy="false" >
          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="hoge_access_log" suffix=".log" rotatable="false"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
     </Host>

     <Host name="fuga.web.non-97.net" appBase="fuga"
          unpackWARs="true" autoDeploy="false" >
          <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="fuga_access_log" suffix=".log" rotatable="false"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
     </Host>
EOF
)
awk -v n=$line_num_engine_end \
  -v s="$insert_text" \
    'NR == n {print s} {print}' ./tomcat10/conf/server.xml \
  > tmpfile && mv -f tmpfile ./tomcat10/conf/server.xml

コンテンツはビルドするのが面倒なのでデフォルトwebappsを流用しました。ただし、examplesは自ホストからしか受け付けるようになっていません。

/usr/local/tomcat10/webapps/examples/META-INF/context.xm

<Context>
  <CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
                   sameSiteCookies="strict" />
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
</Context>

ALB経由でアクセスできるように、ここもAJPコネクターやVirtual Hostと同様にsedを使ってコメントアウトしてあげました。

line_num_comment_start=$(($(grep -n 'org.apache.catalina.valves.RemoteAddrValve' ./tomcat10/webapps/examples/META-INF/context.xml | cut -d : -f 1)-1))
line_num_comment_end=$(($line_num_comment_start+3))

sed "$((${line_num_comment_start}))a <\!\-\-" ./tomcat10/webapps/examples/META-INF/context.xml > tmpfile && mv -f tmpfile ./tomcat10/webapps/examples/META-INF/context.xml
sed "$((${line_num_comment_end}))a \-\->" ./tomcat10/webapps/examples/META-INF/context.xml > tmpfile && mv -f tmpfile ./tomcat10/webapps/examples/META-INF/context.xml

cp -pr ./tomcat10/webapps/ ./tomcat10/hoge
cp -pr ./tomcat10/webapps/ ./tomcat10/fuga

echo "hoge tomcat $(uname -n)" > ./tomcat10/hoge/examples/index.html
echo "fuga tomcat $(uname -n)" > ./tomcat10/fuga/examples/index.html

最後はSELinuxです。

デフォルトだと通信しようとしても500エラーばかり返ってきます。

httpd_can_network_connectを有効化してあげます。

setsebool -P httpd_can_network_connect=true

動作確認

動作確認をしてみます。

デプロイ後、Route 53 Public Hosted ZoneのNSレコードを私のネームサーバーサービスに登録すると、以下のようにhoge.web.non-97.netfuga.web.non-97.netにアクセスできるようになりました。

> curl hoge.web.non-97.net
hoge ip-10-10-10-15.ec2.internal

> curl hoge.web.non-97.net
hoge ip-10-10-10-15.ec2.internal

> curl hoge.web.non-97.net
hoge ip-10-10-10-44.ec2.internal

> curl hoge.web.non-97.net
hoge ip-10-10-10-44.ec2.internal

> curl hoge.web.non-97.net
hoge ip-10-10-10-15.ec2.internal
> curl fuga.web.non-97.net
fuga ip-10-10-10-44.ec2.internal

> curl fuga.web.non-97.net
fuga ip-10-10-10-15.ec2.internal

> curl fuga.web.non-97.net
fuga ip-10-10-10-44.ec2.internal

> curl fuga.web.non-97.net
fuga ip-10-10-10-15.ec2.internal

> curl fuga.web.non-97.net
fuga ip-10-10-10-44.ec2.internal

それぞれアクセスする度にホスト名が変化し、hoge.web.non-97.netfuga.web.non-97.netが返すホスト名が同じであることから、2台のEC2インスタンスのVirtual Hostが動作していることがわかります。

hoge.web.non-97.net/tomcat10/にもアクセスしてみます。

If you're seeing this, you've successfully installed Tomcat. Congratulations!

Tomcatからコンテンツを返すこともできていそうですね。

hoge.web.non-97.net/tomcat10/examples/fuga.web.non-97.net/tomcat10/examples/にもアクセスします。

> curl hoge.web.non-97.net/tomcat10/examples/
hoge tomcat ip-10-10-10-44.ec2.internal

> curl hoge.web.non-97.net/tomcat10/examples/
hoge tomcat ip-10-10-10-15.ec2.internal

> curl hoge.web.non-97.net/tomcat10/examples/
hoge tomcat ip-10-10-10-44.ec2.internal

> curl hoge.web.non-97.net/tomcat10/examples/
hoge tomcat ip-10-10-10-15.ec2.internal

> curl hoge.web.non-97.net/tomcat10/examples/
hoge tomcat ip-10-10-10-15.ec2.internal
> curl fuga.web.non-97.net/tomcat10/examples/
fuga tomcat ip-10-10-10-44.ec2.internal

> curl fuga.web.non-97.net/tomcat10/examples/
fuga tomcat ip-10-10-10-15.ec2.internal

> curl fuga.web.non-97.net/tomcat10/examples/
fuga tomcat ip-10-10-10-15.ec2.internal

> curl fuga.web.non-97.net/tomcat10/examples/
fuga tomcat ip-10-10-10-44.ec2.internal

> curl fuga.web.non-97.net/tomcat10/examples/
fuga tomcat ip-10-10-10-15.ec2.internal

こちらも問題なく表示できていますね。

アクセスログも確認しておきましょう。

まずはhttpdのアクセスログです。

$ sudo ls -l /var/log/httpd/
total 20
-rw-r--r--. 1 root root     0 Aug 23 08:24 access_log
-rw-r--r--. 1 root root   699 Aug 23 08:24 error_log
-rw-r--r--. 1 root root  1500 Aug 23 08:40 fuga_access_log
-rw-r--r--. 1 root root     0 Aug 23 08:24 fuga_error_log
-rw-r--r--. 1 root root 10365 Aug 23 08:41 hoge_access_log
-rw-r--r--. 1 root root     0 Aug 23 08:24 hoge_error_log

$ sudo tail /var/log/httpd/hoge_access_log
10.10.10.60 - - [23/Aug/2023:08:39:40 +0000] "GET /tomcat10/examples/ HTTP/1.1" 200 40 "-" "curl/8.1.2"
10.10.10.60 - - [23/Aug/2023:08:39:49 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.7 - - [23/Aug/2023:08:39:56 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.60 - - [23/Aug/2023:08:40:19 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.7 - - [23/Aug/2023:08:40:26 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.60 - - [23/Aug/2023:08:40:49 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.7 - - [23/Aug/2023:08:40:56 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.60 - - [23/Aug/2023:08:41:19 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.7 - - [23/Aug/2023:08:41:26 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"
10.10.10.60 - - [23/Aug/2023:08:41:49 +0000] "GET / HTTP/1.1" 200 33 "-" "ELB-HealthChecker/2.0"

$ sudo tail /var/log/httpd/fuga_access_log
10.10.10.7 - - [23/Aug/2023:08:37:02 +0000] "GET / HTTP/1.1" 200 33 "-" "curl/8.1.2"
10.10.10.7 - - [23/Aug/2023:08:37:04 +0000] "GET / HTTP/1.1" 200 33 "-" "curl/8.1.2"
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /tomcat10/tomcat.css HTTP/1.1" 200 5542 "http://fuga.web.non-97.net/tomcat10/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /tomcat10/tomcat.svg HTTP/1.1" 200 67795 "http://fuga.web.non-97.net/tomcat10/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /tomcat10/bg-upper.png HTTP/1.1" 200 3103 "http://fuga.web.non-97.net/tomcat10/tomcat.css" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /tomcat10/bg-middle.png HTTP/1.1" 200 1918 "http://fuga.web.non-97.net/tomcat10/tomcat.css" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
10.10.10.60 - - [23/Aug/2023:08:40:01 +0000] "GET /tomcat10/examples/ HTTP/1.1" 200 40 "-" "curl/8.1.2"
10.10.10.60 - - [23/Aug/2023:08:40:02 +0000] "GET /tomcat10/examples/ HTTP/1.1" 200 40 "-" "curl/8.1.2"
10.10.10.60 - - [23/Aug/2023:08:40:04 +0000] "GET /tomcat10/examples/ HTTP/1.1" 200 40 "-" "curl/8.1.2"

続いて、Tomcatのログです。

$ sudo ls -l /usr/local/tomcat10/logs/
total 36
-rw-r-----. 1 tomcat tomcat 12118 Aug 23 08:24 catalina.2023-08-23.log
-rw-r-----. 1 tomcat tomcat 12118 Aug 23 08:24 catalina.out
-rw-r-----. 1 tomcat tomcat   560 Aug 23 08:40 fuga_access_log.log
-rw-r-----. 1 tomcat tomcat  1096 Aug 23 08:39 hoge_access_log.log
-rw-r-----. 1 tomcat tomcat   408 Aug 23 08:24 localhost.2023-08-23.log
-rw-r-----. 1 tomcat tomcat     0 Aug 23 08:24 localhost_access_log.2023-08-23.txt

$ sudo head /usr/local/tomcat10/logs/hoge_access_log.log
10.10.10.60 - - [23/Aug/2023:08:36:41 +0000] "GET / HTTP/1.1" 200 11217
10.10.10.60 - - [23/Aug/2023:08:36:42 +0000] "GET /asf-logo-wide.svg HTTP/1.1" 200 27235
10.10.10.60 - - [23/Aug/2023:08:36:46 +0000] "GET /favicon.ico HTTP/1.1" 200 21630
10.10.10.60 - - [23/Aug/2023:08:37:51 +0000] "GET / HTTP/1.1" 200 11217
10.10.10.7 - - [23/Aug/2023:08:37:54 +0000] "GET / HTTP/1.1" 200 11217
10.10.10.7 - - [23/Aug/2023:08:37:55 +0000] "GET /tomcat.css HTTP/1.1" 200 5542
10.10.10.7 - - [23/Aug/2023:08:37:55 +0000] "GET /bg-middle.png HTTP/1.1" 200 1918
10.10.10.7 - - [23/Aug/2023:08:37:55 +0000] "GET /bg-upper.png HTTP/1.1" 200 3103
10.10.10.7 - - [23/Aug/2023:08:37:55 +0000] "GET /bg-button.png HTTP/1.1" 200 713
10.10.10.7 - - [23/Aug/2023:08:39:15 +0000] "GET / HTTP/1.1" 200 11217

$ sudo head /usr/local/tomcat10/logs/fuga_access_log.log
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /tomcat.css HTTP/1.1" 200 5542
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /tomcat.svg HTTP/1.1" 200 67795
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /bg-upper.png HTTP/1.1" 200 3103
10.10.10.7 - - [23/Aug/2023:08:39:08 +0000] "GET /bg-middle.png HTTP/1.1" 200 1918
10.10.10.60 - - [23/Aug/2023:08:40:01 +0000] "GET /examples/ HTTP/1.1" 200 40
10.10.10.60 - - [23/Aug/2023:08:40:02 +0000] "GET /examples/ HTTP/1.1" 200 40
10.10.10.60 - - [23/Aug/2023:08:40:04 +0000] "GET /examples/ HTTP/1.1" 200 40

Catalinaのログも確認しておきましょう。

$ sudo cat /usr/local/tomcat10/logs/catalina.2023-08-23.log
23-Aug-2023 08:24:26.692 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/10.1.12
23-Aug-2023 08:24:26.742 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Aug 8 2023 19:16:13 UTC
23-Aug-2023 08:24:26.743 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.1.12.0
23-Aug-2023 08:24:26.743 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
23-Aug-2023 08:24:26.743 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            5.14.0-284.18.1.el9_2.x86_64
23-Aug-2023 08:24:26.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
23-Aug-2023 08:24:26.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/lib/jvm/java-17-openjdk-17.0.8.0.7-2.el9.x86_64
23-Aug-2023 08:24:26.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           17.0.8+7-LTS
23-Aug-2023 08:24:26.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Red Hat, Inc.
23-Aug-2023 08:24:26.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/apache-tomcat-10.1.12
23-Aug-2023 08:24:26.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/apache-tomcat-10.1.12
23-Aug-2023 08:24:26.988 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat10/conf/logging.properties
23-Aug-2023 08:24:26.989 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
23-Aug-2023 08:24:26.989 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
23-Aug-2023 08:24:26.989 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
23-Aug-2023 08:24:26.989 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
23-Aug-2023 08:24:26.989 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
23-Aug-2023 08:24:26.989 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
23-Aug-2023 08:24:26.990 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Xms512m
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Xmx512m
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Xss512k
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -XX:MetaspaceSize=512m
23-Aug-2023 08:24:26.991 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.security.egd=file:/dev/urandom
23-Aug-2023 08:24:27.008 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat10
23-Aug-2023 08:24:27.008 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat10
23-Aug-2023 08:24:27.008 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat10/temp
23-Aug-2023 08:24:27.015 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path: [/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib]
23-Aug-2023 08:24:29.172 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
23-Aug-2023 08:24:29.425 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-0:0:0:0:0:0:0:1-8009"]
23-Aug-2023 08:24:29.428 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [4517] milliseconds
23-Aug-2023 08:24:29.641 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
23-Aug-2023 08:24:29.642 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.1.12]
23-Aug-2023 08:24:29.741 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/webapps/ROOT]
23-Aug-2023 08:24:31.942 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/webapps/ROOT] has finishedin [2,200] ms
23-Aug-2023 08:24:31.953 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/webapps/docs]
23-Aug-2023 08:24:32.315 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/webapps/docs] has finishedin [361] ms
23-Aug-2023 08:24:32.319 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/webapps/examples]
23-Aug-2023 08:24:34.006 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/webapps/examples] has finished in [1,687] ms
23-Aug-2023 08:24:34.008 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/webapps/host-manager]
23-Aug-2023 08:24:34.103 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/webapps/host-manager] has finished in [94] ms
23-Aug-2023 08:24:34.111 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/webapps/manager]
23-Aug-2023 08:24:34.183 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/webapps/manager] has finished in [72] ms
23-Aug-2023 08:24:34.192 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/hoge/docs]
23-Aug-2023 08:24:34.354 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/hoge/docs] has finished in[162] ms
23-Aug-2023 08:24:34.354 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/hoge/manager]
23-Aug-2023 08:24:34.438 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/hoge/manager] has finishedin [83] ms
23-Aug-2023 08:24:34.438 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/hoge/host-manager]
23-Aug-2023 08:24:34.554 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/hoge/host-manager] has finished in [115] ms
23-Aug-2023 08:24:34.554 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/hoge/ROOT]
23-Aug-2023 08:24:34.589 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/hoge/ROOT] has finished in[35] ms
23-Aug-2023 08:24:34.590 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/hoge/examples]
23-Aug-2023 08:24:35.218 INFO [main] org.apache.catalina.core.ApplicationContext.log ContextListener: contextInitialized()
23-Aug-2023 08:24:35.218 INFO [main] org.apache.catalina.core.ApplicationContext.log SessionListener: contextInitialized()
23-Aug-2023 08:24:35.222 INFO [main] org.apache.catalina.core.ApplicationContext.log ContextListener: attributeAdded('StockTicker', 'async.Stockticker@5bb3d42d')
23-Aug-2023 08:24:35.234 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/hoge/examples] has finished in [644] ms
23-Aug-2023 08:24:35.236 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/fuga/docs]
23-Aug-2023 08:24:35.334 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/fuga/docs] has finished in[98] ms
23-Aug-2023 08:24:35.335 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/fuga/manager]
23-Aug-2023 08:24:35.430 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/fuga/manager] has finishedin [95] ms
23-Aug-2023 08:24:35.430 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/fuga/host-manager]
23-Aug-2023 08:24:35.497 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/fuga/host-manager] has finished in [66] ms
23-Aug-2023 08:24:35.497 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/fuga/ROOT]
23-Aug-2023 08:24:35.568 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/fuga/ROOT] has finished in[70] ms
23-Aug-2023 08:24:35.568 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-10.1.12/fuga/examples]
23-Aug-2023 08:24:35.998 INFO [main] org.apache.catalina.core.ApplicationContext.log ContextListener: contextInitialized()
23-Aug-2023 08:24:35.998 INFO [main] org.apache.catalina.core.ApplicationContext.log SessionListener: contextInitialized()
23-Aug-2023 08:24:36.000 INFO [main] org.apache.catalina.core.ApplicationContext.log ContextListener: attributeAdded('StockTicker', 'async.Stockticker@3703bf3c')
23-Aug-2023 08:24:36.012 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-10.1.12/fuga/examples] has finished in [443] ms
23-Aug-2023 08:24:36.030 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
23-Aug-2023 08:24:36.271 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-0:0:0:0:0:0:0:1-8009"]
23-Aug-2023 08:24:36.300 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [6866] milliseconds

ついでにjournalに記録されたTomcatのサービスのログも確認します。

$ journalctl -xu tomcat10
Aug 23 08:24:21 ip-10-10-10-15.ec2.internal systemd[1]: Starting Apache Tomcat Web Application Container...
░░ Subject: A start job for unit tomcat10.service has begun execution
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░
░░ A start job for unit tomcat10.service has begun execution.
░░
░░ The job identifier is 1274.
Aug 23 08:24:21 ip-10-10-10-15.ec2.internal startup.sh[11204]: Tomcat started.
Aug 23 08:24:21 ip-10-10-10-15.ec2.internal systemd[1]: Finished Apache Tomcat Web Application Container.
░░ Subject: A start job for unit tomcat10.service has finished successfully
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░
░░ A start job for unit tomcat10.service has finished successfully.
░░
░░ The job identifier is 1274.

シェルスクリプトで頑張ればなんとかできます

Apache HTTP ServerとApache TomcatのVirtual Hostが動作しているEC2インスタンスをAuto ScalingさせてALBで接続できる環境を一撃で用意しました。

シェルスクリプトで頑張ればなんとかできますね。シェルスクリプト最高です。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!