サイトアイコン 協栄情報ブログ

AWS CDKによる【EC2】の構築

皆様こんにちは。
AWS CDKを利用してマルチAZ3層アーキテクチャ構築をしていきます。
この記事ではEC2の作成を行います。

目次はこちら

1.EC2とは

Amazon EC2 (Elastic Compute Cloud) は、Amazon Web Services (AWS) が提供する仮想サーバーを簡単に作成、管理できるサービスです。

概要

主な機能

Amazon EC2 を使用することで、企業はインフラストラクチャの運用や管理の負担を軽減し、迅速にアプリケーションの展開やスケーリングが可能になります。
詳細は公式ドキュメントを参照ください。

2.目的

3.構成図

4.全体構築ソースコード

        # IAM インスタンスプロファイルの作成
        self.instance_profile = iam.CfnInstanceProfile(self, "kitaya-instance-profile",
            roles=[ec2_role.role_name]
        )

        # ユーザーデータ#1号機
        user_data_script_01 = """#!/bin/bash
# Secrets Managerからシークレットを取得
SECRET=$(aws secretsmanager get-secret-value --secret-id kitaya-db-Secret --query SecretString --output text)

# 環境変数の設定
export EFS_DNS="EFSのDNS名"
export MYSQL_HOST="RDSのDNS名"
export MYSQL_USER=$(echo "$SECRET" | jq -r .username)
export MYSQL_PASSWORD=$(echo "$SECRET" | jq -r .password)
export MYSQL_DBNAME="データベース名"

# 更新を行う
dnf update -y

# Apache HTTPサーバーをインストール
dnf install -y httpd

# EFSファイルシステム用のディレクトリを作成
mkdir -p /mnt/efs

# EFSファイルシステムをマウント
mount -t nfs4 "${EFS_DNS}:/" /mnt/efs

# EFSのマウントを永続化
grep -q "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" /etc/fstab || echo "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" >> /etc/fstab

# MySQLクライアントのインストール
dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
dnf -y install mysql-community-client

# PHPとApacheのPHPモジュールのインストール
dnf install -y php php-cli php-fpm php-mysqlnd php-json php-opcache php-gd php-xml php-mbstring
dnf update -y

# Apache MPMをpreforkに設定
echo "LoadModule mpm_prefork_module modules/mod_mpm_prefork.so" | sudo tee /etc/httpd/conf.modules.d/00-mpm.conf

# Apacheの設定変更
sed -i 's|DocumentRoot "/var/www/html"|DocumentRoot "/mnt/efs"|g' /etc/httpd/conf/httpd.conf
sed -i 's|<Directory "/var/www/html">|<Directory "/mnt/efs">|g' /etc/httpd/conf/httpd.conf
sed -i 's/index.html/index01.php/g' /etc/httpd/conf/httpd.conf

# PHP-FPMの設定
systemctl start php-fpm
systemctl enable php-fpm

# Apache設定にPHP-FPMの設定を追加
cat <<EOF > /etc/httpd/conf.d/php.conf
<FilesMatch \.php$>
  SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost/"
</FilesMatch>
EOF

# Apacheの起動と自動起動の設定
systemctl start httpd
systemctl enable httpd

# データベース設定ファイルの作成(DB名だけ変更)
cat <<EOF > /mnt/efs/db_config.php
<?php
\$db_config = [
  'servername' => '$MYSQL_HOST',
  'username' => '$MYSQL_USER',
  'password' => '$MYSQL_PASSWORD',
  'dbname' => '$MYSQL_DBNAME'
];
?>
EOF

# PHPファイルの作成(変更箇所あり)
cat <<EOF > /mnt/efs/index01.php
<?php
include 'db_config.php';

// データベース接続の設定
\$servername = \$db_config['servername'];
\$username = \$db_config['username'];
\$password = \$db_config['password'];
\$dbname = \$db_config['dbname'];

// MySQLデータベースに接続
\$conn = new mysqli(\$servername, \$username, \$password, \$dbname);

// UTF-8でエンコーディングを設定
\$conn->set_charset("utf8");

// 接続をチェックする
if (\$conn->connect_error) {
  die("接続に失敗しました: " . \$conn->connect_error);
}

// employeesテーブルからデータを取得するクエリ
\$sql = "SELECT * FROM employees";
\$result = \$conn->query(\$sql);

// クエリの実行をチェックする
if (!\$result) {
  die("クエリの実行に失敗しました: " . \$conn->error);
}

// HTMLの文字コードを指定
echo "<meta charset='UTF-8'>";

// タイトルを表示
echo "<h1>WEBサーバー 1号機</h1>";

// データが取得できた場合、HTMLテーブルとして表示する
if (\$result->num_rows > 0) {
  echo "<table border='1'>";
  echo "<tr><th>Employee ID</th><th>First Name</th><th>Last Name</th><th>Email</th><th>Hire Date</th><th>Salary</th><th>Department ID</th></tr>";
  while(\$row = \$result->fetch_assoc()) {
      echo "<tr>";
      echo "<td>".\$row["employee_id"]."</td>";
      echo "<td>".\$row["first_name"]."</td>";
      echo "<td>".\$row["last_name"]."</td>";
      echo "<td>".\$row["email"]."</td>";
      echo "<td>".\$row["hire_date"]."</td>";
      echo "<td>".\$row["salary"]."</td>";
      echo "<td>".\$row["department_id"]."</td>";
      echo "</tr>";
  }
  echo "</table>";
} else {
  echo "データが見つかりませんでした";
}

// MySQL接続を閉じる
\$conn->close();
?>
EOF

# ALBのヘルスチェック用のHTMLファイルの作成
cat <<EOF > /mnt/efs/healthcheck.php
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Health Check</title>
</head>
<body>
  <h1>ALB Health Check Passed</h1>
</body>
</html>
EOF

# CloudWatchエージェントのインストール
yum install -y amazon-cloudwatch-agent

# MySQLデータベースの設定(CREATE TABLE)
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD <<EOF
USE kitaya_rds;

CREATE TABLE IF NOT EXISTS employees (
  employee_id INT AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(50) NOT NULL,
  last_name VARCHAR(50) NOT NULL,
  email VARCHAR(100),
  hire_date DATE,
  salary DECIMAL(10, 2),
  department_id INT
);

INSERT INTO employees (first_name, last_name, email, hire_date, salary, department_id)
VALUES
  ('Alice', 'Smith', 'alice.smith@example.com', '2023-01-15', 60000.00, 1),
  ('Bob', 'Johnson', 'bob.johnson@example.com', '2023-02-20', 55000.00, 2),
  ('Charlie', 'Williams', 'charlie.williams@example.com', '2023-03-25', 65000.00, 1),
  ('David', 'Brown', 'david.brown@example.com', '2023-04-30', 70000.00, 2),
  ('Eva', 'Garcia', 'eva.garcia@example.com', '2023-05-05', 58000.00, 1);

UPDATE employees
SET salary = 55000.00
WHERE employee_id = 1;
EOF
"""

ユーザーデータ#2号機

# ユーザーデータ#2号機
user_data_script_02 = """#!/bin/bash
# 環境変数の設定
export EFS_DNS="EFSのDNS名"

# 更新を行う
dnf update -y

# Apache HTTPサーバーをインストール
dnf install -y httpd

# EFSファイルシステム用のディレクトリを作成
mkdir -p /mnt/efs

# EFSファイルシステムをマウント
mount -t nfs4 "${EFS_DNS}:/" /mnt/efs

# EFSのマウントを永続化
grep -q "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" /etc/fstab || echo "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" >> /etc/fstab

# MySQLクライアントのインストール
dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
dnf -y install mysql-community-client

# PHPとApacheのPHPモジュールのインストール
dnf install -y php php-cli php-fpm php-mysqlnd php-json php-opcache php-gd php-xml php-mbstring
dnf update -y

# Apache MPMをpreforkに設定
echo "LoadModule mpm_prefork_module modules/mod_mpm_prefork.so" | sudo tee /etc/httpd/conf.modules.d/00-mpm.conf

# Apacheの設定変更
sed -i 's|DocumentRoot "/var/www/html"|DocumentRoot "/mnt/efs"|g' /etc/httpd/conf/httpd.conf
sed -i 's|<Directory "/var/www/html">|<Directory "/mnt/efs">|g' /etc/httpd/conf/httpd.conf
sed -i 's/index.html/index02.php/g' /etc/httpd/conf/httpd.conf

# PHP-FPMの設定
systemctl start php-fpm
systemctl enable php-fpm

# Apache設定にPHP-FPMの設定を追加
cat <<EOF > /etc/httpd/conf.d/php.conf
<FilesMatch \.php$>
  SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost/"
</FilesMatch>
EOF

# Apacheの起動と自動起動の設定
systemctl start httpd
systemctl enable httpd

# PHPファイルの作成(変更箇所あり)
cat <<EOF > /mnt/efs/index02.php
<?php
include 'db_config.php';

// データベース接続の設定
\$servername = \$db_config['servername'];
\$username = \$db_config['username'];
\$password = \$db_config['password'];
\$dbname = \$db_config['dbname'];

// MySQLデータベースに接続
\$conn = new mysqli(\$servername, \$username, \$password, \$dbname);

// UTF-8でエンコーディングを設定
\$conn->set_charset("utf8");

// 接続をチェックする
if (\$conn->connect_error) {
  die("接続に失敗しました: " . \$conn->connect_error);
}

// employeesテーブルからデータを取得するクエリ
\$sql = "SELECT * FROM employees";
\$result = \$conn->query(\$sql);

// クエリの実行をチェックする
if (!\$result) {
  die("クエリの実行に失敗しました: " . \$conn->error);
}

// HTMLの文字コードを指定
echo "<meta charset='UTF-8'>";

// タイトルを表示
echo "<h1>WEBサーバー 2号機</h1>";

// データが取得できた場合、HTMLテーブルとして表示する
if (\$result->num_rows > 0) {
  echo "<table border='1'>";
  echo "<tr><th>Employee ID</th><th>First Name</th><th>Last Name</th><th>Email</th><th>Hire Date</th><th>Salary</th><th>Department ID</th></tr>";
  while(\$row = \$result->fetch_assoc()) {
      echo "<tr>";
      echo "<td>".\$row["employee_id"]."</td>";
      echo "<td>".\$row["first_name"]."</td>";
      echo "<td>".\$row["last_name"]."</td>";
      echo "<td>".\$row["email"]."</td>";
      echo "<td>".\$row["hire_date"]."</td>";
      echo "<td>".\$row["salary"]."</td>";
      echo "<td>".\$row["department_id"]."</td>";
      echo "</tr>";
  }
  echo "</table>";
} else {
  echo "データが見つかりませんでした";
}

// MySQL接続を閉じる
\$conn->close();
?>
EOF

# CloudWatchエージェントのインストール
yum install -y amazon-cloudwatch-agent
"""

        # Webサーバ #1(EC2)の作成
        self.instance_01 = ec2.CfnInstance(self, "kitaya-ec2-2a",
            image_id="ami-045f2d6eeb07ce8c0",
            instance_type="t3.micro",
            key_name="kitaya-kp-ec2",
            iam_instance_profile=self.instance_profile.ref,
            network_interfaces=[{
                "subnetId": private_subnet_az1.ref,
                "associatePublicIpAddress": False,
                "deviceIndex": "0",
                "privateIpAddress": "192.168.1.134",
                "groupSet": [ec2_sg.security_group_id]
            }],
            block_device_mappings=[
                {
                    "deviceName": "/dev/xvda",
                    "ebs": {
                        "volumeSize": 8,
                        "volumeType": "gp3",
                        "iops": 3000,
                        "throughput": 125,
                        "encrypted": True,
                        "deleteOnTermination": True,
                    }
                }
            ],
            user_data=Fn.base64(user_data_script_01)
        )
        Tags.of(self.instance_01).add("Name", "kitaya-ec2-2a")

        # Webサーバ #2(EC2)の作成
        self.instance_02 = ec2.CfnInstance(self, "kitaya-ec2-2b",
            image_id="ami-045f2d6eeb07ce8c0",
            instance_type="t3.micro",
            key_name="kitaya-kp-ec2",
            iam_instance_profile=self.instance_profile.ref,
            network_interfaces=[{
                "subnetId": private_subnet_az2.ref,
                "associatePublicIpAddress": False,
                "deviceIndex": "0",
                "privateIpAddress": "192.168.1.155",
                "groupSet": [ec2_sg.security_group_id]
            }],
            block_device_mappings=[
                {
                    "deviceName": "/dev/xvda",
                    "ebs": {
                        "volumeSize": 8,
                        "volumeType": "gp3",
                        "iops": 3000,
                        "throughput": 125,
                        "encrypted": True,
                        "deleteOnTermination": True,
                    }
                }
            ],
            user_data=Fn.base64(user_data_script_02)
        )
        Tags.of(self.instance_02).add("Name", "kitaya-ec2-2b")

5.ソースコード詳細

5-1.IAM インスタンスプロファイルの作成

インスタンスプロファイルはIAMロールのコンテナであり、インスタンスの起動時にEC2インスタンスにロール情報を渡すために使用できます。
マネジメントコンソールでEC2にアタッチする際にはインスタンスプロファイルは自動的に作成されるため意識することはありません。
IaCでの構築の場合は作成必須の項目となります。

"CfnInstanceProfile"を使用

論理ID(テンプレート内で一意)の指定をしたのち、詳細のプロパティを指定しています。

プロパティは下記

使用するプロパティ 設定値 説明
roles [ec2_role.role_name] インスタンスプロファイルに関連付ける IAM ロールのリストです。このリストには、少なくとも1つの IAM ロールが含まれている必要があります。今回は事前に作成したものを指定します。

ソースコード

        # IAM インスタンスプロファイルの作成
        self.instance_profile = iam.CfnInstanceProfile(self, "kitaya-instance-profile",
            roles=[ec2_role.role_name]
        )

5-2.ユーザーデータの作成

ユーザーデータとは、EC2インスタンスの起動時に一度だけ実行されるスクリプトやコマンドを指定するためのメカニズムです。ユーザーデータを使用して、インスタンスの起動時に自動的にソフトウェアをインストールしたり、設定を行ったりすることができます。

ユーザーデータの内容は下記です。
1号機と2号機でユーザーデータを少し変えています。
共用のものについては1号機でのみ実行しています。

1号機、2号機それぞれで実行

共用のため1号機のみで実行

ソースコード

        # ユーザーデータ#1号機
        user_data_script_01 = """#!/bin/bash
# Secrets Managerからシークレットを取得
SECRET=$(aws secretsmanager get-secret-value --secret-id kitaya-db-Secret --query SecretString --output text)

# 環境変数の設定
export EFS_DNS="EFSのDNS名"
export MYSQL_HOST="RDSのDNS名"
export MYSQL_USER=$(echo "$SECRET" | jq -r .username)
export MYSQL_PASSWORD=$(echo "$SECRET" | jq -r .password)
export MYSQL_DBNAME="データベース名"

# 更新を行う
dnf update -y

# Apache HTTPサーバーをインストール
dnf install -y httpd

# EFSファイルシステム用のディレクトリを作成
mkdir -p /mnt/efs

# EFSファイルシステムをマウント
mount -t nfs4 "${EFS_DNS}:/" /mnt/efs

# EFSのマウントを永続化
grep -q "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" /etc/fstab || echo "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" >> /etc/fstab

# MySQLクライアントのインストール
dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
dnf -y install mysql-community-client

# PHPとApacheのPHPモジュールのインストール
dnf install -y php php-cli php-fpm php-mysqlnd php-json php-opcache php-gd php-xml php-mbstring
dnf update -y

# Apache MPMをpreforkに設定
echo "LoadModule mpm_prefork_module modules/mod_mpm_prefork.so" | sudo tee /etc/httpd/conf.modules.d/00-mpm.conf

# Apacheの設定変更
sed -i 's|DocumentRoot "/var/www/html"|DocumentRoot "/mnt/efs"|g' /etc/httpd/conf/httpd.conf
sed -i 's|<Directory "/var/www/html">|<Directory "/mnt/efs">|g' /etc/httpd/conf/httpd.conf
sed -i 's/index.html/index01.php/g' /etc/httpd/conf/httpd.conf

# PHP-FPMの設定
systemctl start php-fpm
systemctl enable php-fpm

# Apache設定にPHP-FPMの設定を追加
cat <<EOF > /etc/httpd/conf.d/php.conf
<FilesMatch \.php$>
  SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost/"
</FilesMatch>
EOF

# Apacheの起動と自動起動の設定
systemctl start httpd
systemctl enable httpd

# データベース設定ファイルの作成(DB名だけ変更)
cat <<EOF > /mnt/efs/db_config.php
<?php
\$db_config = [
  'servername' => '$MYSQL_HOST',
  'username' => '$MYSQL_USER',
  'password' => '$MYSQL_PASSWORD',
  'dbname' => '$MYSQL_DBNAME'
];
?>
EOF

# PHPファイルの作成(変更箇所あり)
cat <<EOF > /mnt/efs/index01.php
<?php
include 'db_config.php';

// データベース接続の設定
\$servername = \$db_config['servername'];
\$username = \$db_config['username'];
\$password = \$db_config['password'];
\$dbname = \$db_config['dbname'];

// MySQLデータベースに接続
\$conn = new mysqli(\$servername, \$username, \$password, \$dbname);

// UTF-8でエンコーディングを設定
\$conn->set_charset("utf8");

// 接続をチェックする
if (\$conn->connect_error) {
  die("接続に失敗しました: " . \$conn->connect_error);
}

// employeesテーブルからデータを取得するクエリ
\$sql = "SELECT * FROM employees";
\$result = \$conn->query(\$sql);

// クエリの実行をチェックする
if (!\$result) {
  die("クエリの実行に失敗しました: " . \$conn->error);
}

// HTMLの文字コードを指定
echo "<meta charset='UTF-8'>";

// タイトルを表示
echo "<h1>WEBサーバー 1号機</h1>";

// データが取得できた場合、HTMLテーブルとして表示する
if (\$result->num_rows > 0) {
  echo "<table border='1'>";
  echo "<tr><th>Employee ID</th><th>First Name</th><th>Last Name</th><th>Email</th><th>Hire Date</th><th>Salary</th><th>Department ID</th></tr>";
  while(\$row = \$result->fetch_assoc()) {
      echo "<tr>";
      echo "<td>".\$row["employee_id"]."</td>";
      echo "<td>".\$row["first_name"]."</td>";
      echo "<td>".\$row["last_name"]."</td>";
      echo "<td>".\$row["email"]."</td>";
      echo "<td>".\$row["hire_date"]."</td>";
      echo "<td>".\$row["salary"]."</td>";
      echo "<td>".\$row["department_id"]."</td>";
      echo "</tr>";
  }
  echo "</table>";
} else {
  echo "データが見つかりませんでした";
}

// MySQL接続を閉じる
\$conn->close();
?>
EOF

# ALBのヘルスチェック用のHTMLファイルの作成
cat <<EOF > /mnt/efs/healthcheck.php
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Health Check</title>
</head>
<body>
  <h1>ALB Health Check Passed</h1>
</body>
</html>
EOF

# CloudWatchエージェントのインストール
yum install -y amazon-cloudwatch-agent

# MySQLデータベースの設定(CREATE TABLE)
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD <<EOF
USE kitaya_rds;

CREATE TABLE IF NOT EXISTS employees (
  employee_id INT AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(50) NOT NULL,
  last_name VARCHAR(50) NOT NULL,
  email VARCHAR(100),
  hire_date DATE,
  salary DECIMAL(10, 2),
  department_id INT
);

INSERT INTO employees (first_name, last_name, email, hire_date, salary, department_id)
VALUES
  ('Alice', 'Smith', 'alice.smith@example.com', '2023-01-15', 60000.00, 1),
  ('Bob', 'Johnson', 'bob.johnson@example.com', '2023-02-20', 55000.00, 2),
  ('Charlie', 'Williams', 'charlie.williams@example.com', '2023-03-25', 65000.00, 1),
  ('David', 'Brown', 'david.brown@example.com', '2023-04-30', 70000.00, 2),
  ('Eva', 'Garcia', 'eva.garcia@example.com', '2023-05-05', 58000.00, 1);

UPDATE employees
SET salary = 55000.00
WHERE employee_id = 1;
EOF
"""

        # ユーザーデータ#2号機
        user_data_script_02 = """#!/bin/bash
# 環境変数の設定
export EFS_DNS="EFSのDNS名"

# 更新を行う
dnf update -y

# Apache HTTPサーバーをインストール
dnf install -y httpd

# EFSファイルシステム用のディレクトリを作成
mkdir -p /mnt/efs

# EFSファイルシステムをマウント
mount -t nfs4 "${EFS_DNS}:/" /mnt/efs

# EFSのマウントを永続化
grep -q "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" /etc/fstab || echo "${EFS_DNS}:/ /mnt/efs nfs4 defaults,_netdev 0 0" >> /etc/fstab

# MySQLクライアントのインストール
dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
dnf -y install mysql-community-client

# PHPとApacheのPHPモジュールのインストール
dnf install -y php php-cli php-fpm php-mysqlnd php-json php-opcache php-gd php-xml php-mbstring
dnf update -y

# Apache MPMをpreforkに設定
echo "LoadModule mpm_prefork_module modules/mod_mpm_prefork.so" | sudo tee /etc/httpd/conf.modules.d/00-mpm.conf

# Apacheの設定変更
sed -i 's|DocumentRoot "/var/www/html"|DocumentRoot "/mnt/efs"|g' /etc/httpd/conf/httpd.conf
sed -i 's|<Directory "/var/www/html">|<Directory "/mnt/efs">|g' /etc/httpd/conf/httpd.conf
sed -i 's/index.html/index02.php/g' /etc/httpd/conf/httpd.conf

# PHP-FPMの設定
systemctl start php-fpm
systemctl enable php-fpm

# Apache設定にPHP-FPMの設定を追加
cat <<EOF > /etc/httpd/conf.d/php.conf
<FilesMatch \.php$>
  SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost/"
</FilesMatch>
EOF

# Apacheの起動と自動起動の設定
systemctl start httpd
systemctl enable httpd

# PHPファイルの作成(変更箇所あり)
cat <<EOF > /mnt/efs/index02.php
<?php
include 'db_config.php';

// データベース接続の設定
\$servername = \$db_config['servername'];
\$username = \$db_config['username'];
\$password = \$db_config['password'];
\$dbname = \$db_config['dbname'];

// MySQLデータベースに接続
\$conn = new mysqli(\$servername, \$username, \$password, \$dbname);

// UTF-8でエンコーディングを設定
\$conn->set_charset("utf8");

// 接続をチェックする
if (\$conn->connect_error) {
  die("接続に失敗しました: " . \$conn->connect_error);
}

// employeesテーブルからデータを取得するクエリ
\$sql = "SELECT * FROM employees";
\$result = \$conn->query(\$sql);

// クエリの実行をチェックする
if (!\$result) {
  die("クエリの実行に失敗しました: " . \$conn->error);
}

// HTMLの文字コードを指定
echo "<meta charset='UTF-8'>";

// タイトルを表示
echo "<h1>WEBサーバー 2号機</h1>";

// データが取得できた場合、HTMLテーブルとして表示する
if (\$result->num_rows > 0) {
  echo "<table border='1'>";
  echo "<tr><th>Employee ID</th><th>First Name</th><th>Last Name</th><th>Email</th><th>Hire Date</th><th>Salary</th><th>Department ID</th></tr>";
  while(\$row = \$result->fetch_assoc()) {
      echo "<tr>";
      echo "<td>".\$row["employee_id"]."</td>";
      echo "<td>".\$row["first_name"]."</td>";
      echo "<td>".\$row["last_name"]."</td>";
      echo "<td>".\$row["email"]."</td>";
      echo "<td>".\$row["hire_date"]."</td>";
      echo "<td>".\$row["salary"]."</td>";
      echo "<td>".\$row["department_id"]."</td>";
      echo "</tr>";
  }
  echo "</table>";
} else {
  echo "データが見つかりませんでした";
}

// MySQL接続を閉じる
\$conn->close();
?>
EOF

# CloudWatchエージェントのインストール
yum install -y amazon-cloudwatch-agent

5-3.EC2インスタンスの作成

EC2インスタンスを作成します。

"ec2.CfnInstance"を使用を使用して作成

論理ID(テンプレート内で一意)の指定をしたのち、詳細のプロパティを指定しています。

プロパティは下記

使用するプロパティ 設定値 説明
image_id "ami-045f2d6eeb07ce8c0" AmazonMachineImage(AMI)のID。このAMIを使用してインスタンスを起動します。
instance_type "t3.micro" EC2インスタンスタイプ。t3.microは小規模なインスタンスです。
key_name "kitaya-kp-ec2" インスタンスにアクセスするためのキーペアの名前です。
iam_instance_profile self.instance_profile.ref インスタンスにアタッチするIAMインスタンスプロファイルの参照です。
network_interfaces 下記にて詳細説明 ネットワークインターフェースの設定
block_device_mappings 下記にて詳細説明 EBSの設定
user_data Fn.base64(ソースコード参照) インスタンスの起動時に実行するユーザーデータスクリプトを指定。

network_interfaces

使用するプロパティ 設定値 説明
subnetId ソースコード参照 ネットワークインターフェースが所属するサブネットのID。
associatePublicIpAddress False パブリックIPアドレスを割り当てるかどうかの設定。
deviceIndex "0" ネットワークインターフェースのデバイスインデックス。
privateIpAddress ソースコード参照 ネットワークインターフェースに割り当てるプライベートIPアドレス。
groupSet [ec2_sg.security_group_id] ネットワークインターフェースに関連付けるセキュリティグループのIDリスト。

block_device_mappings

使用するプロパティ 設定値 説明
deviceName "/dev/xvda" ブロックデバイスの名前。
ebs.volumeSize 8 EBSボリュームのサイズ(GB)。
ebs.volumeType "gp3" EBSボリュームのタイプ。gp3は汎用SSD。
ebs.iops 3000 EBSボリュームのIOPS(Input/OutputOperationsPerSecond)。
ebs.throughput 125 EBSボリュームのスループット(MB/s)。
ebs.encrypted True EBSボリュームが暗号化されているかどうかの設定。
ebs.deleteOnTermination True インスタンス終了時にEBSボリュームを削除するかどうかの設定。

"Tags.of()"メソッドを使用してNameタグをつけます(書式は下記)

Tags.of("リソース名").add("キー", "値")

ソースコード

        # Webサーバ #1(EC2)の作成
        self.instance_01 = ec2.CfnInstance(self, "kitaya-ec2-2a",
            image_id="ami-045f2d6eeb07ce8c0",
            instance_type="t3.micro",
            key_name="kitaya-kp-ec2",
            iam_instance_profile=self.instance_profile.ref,
            network_interfaces=[{
                "subnetId": private_subnet_az1.ref,
                "associatePublicIpAddress": False,
                "deviceIndex": "0",
                "privateIpAddress": "192.168.1.134",
                "groupSet": [ec2_sg.security_group_id]
            }],
            block_device_mappings=[
                {
                    "deviceName": "/dev/xvda",
                    "ebs": {
                        "volumeSize": 8,
                        "volumeType": "gp3",
                        "iops": 3000,
                        "throughput": 125,
                        "encrypted": True,
                        "deleteOnTermination": True,
                    }
                }
            ],
            user_data=Fn.base64(user_data_script_01)
        )
        Tags.of(self.instance_01).add("Name", "kitaya-ec2-2a")

        # Webサーバ #2(EC2)の作成
        self.instance_02 = ec2.CfnInstance(self, "kitaya-ec2-2b",
            image_id="ami-045f2d6eeb07ce8c0",
            instance_type="t3.micro",
            key_name="kitaya-kp-ec2",
            iam_instance_profile=self.instance_profile.ref,
            network_interfaces=[{
                "subnetId": private_subnet_az2.ref,
                "associatePublicIpAddress": False,
                "deviceIndex": "0",
                "privateIpAddress": "192.168.1.155",
                "groupSet": [ec2_sg.security_group_id]
            }],
            block_device_mappings=[
                {
                    "deviceName": "/dev/xvda",
                    "ebs": {
                        "volumeSize": 8,
                        "volumeType": "gp3",
                        "iops": 3000,
                        "throughput": 125,
                        "encrypted": True,
                        "deleteOnTermination": True,
                    }
                }
            ],
            user_data=Fn.base64(user_data_script_02)
        )
        Tags.of(self.instance_02).add("Name", "kitaya-ec2-2b")

6.検証

Webページの表示等、検証についてはALB構築にて行います。

7.感想

EC2の構築はインスタンスの設定のみではなく、ユーザーデータの作成など考慮する点が多く時間がかかった。
データベースなどの知識も少し学習できてよかった。

モバイルバージョンを終了