はじめに
CDK の勉強がてらに、Amazon Linux2023 + Aurora Serverlessv2 の Laravel 環境を構築してみました。
本記事は、備忘録用のメモになります。
前提条件
- AWS CLI がインストールされていること
- CDK がインストールされているかつ、
BootStrap
スタックが作成されていること。
動作環境
- macOS Ventura 13.4
- CDK: 2.134.0 (build 265d769)
- AWS CLI: aws-cli/2.15.2 Python/3.11.6 Darwin/23.4.0 exe/x86_64 prompt/off
CDK のプロジェクトの作成
-
プロジェクト用ディレクトリを作成する
mkdir cdk-laravel cd cdk-laravel
-
CDK init を実行する。
cdk init app --language typescript
これで CDK の構築準備が整いました。
ネットワーク関連の構築
VPC やサブネットなどネットワーク関連のリソースを作成していきます。
+ import { aws_ec2 as ec2 } from "aws-cdk-lib";
export class CdkLaravelStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
+ const vpc = new ec2.Vpc(this, "vpc", {
+ maxAzs: 2,
+ natGateways: 0,
+ subnetConfiguration: [
+ {
+ cidrMask: 24,
+ name: "public",
+ subnetType: ec2.SubnetType.PUBLIC,
+ },
+ {
+ cidrMask: 24,
+ name: "private",
+ subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
+ },
+ ],
+ });
NAT ゲートウェイを作成すると料金がかかるので、natGateways: 0
で作成されないようにします。
EC2 Instance Connect Endpoint の構築
リソースの作成
EC2 Instance Connect Endpoint を使用することで、簡単に EC2 に接続することができるようになりますので、こちらを作成します。
なお、EC2 Instance Connect Endpoint は料金はかかりませんので、ご安心ください。
※ファイル内の全てのコードを記載すると記述が長くなりますので、追記した箇所のみ記載させていただきます
const eicSg = new ec2.SecurityGroup(this, "eic_sg", {
vpc,
allowAllOutbound: false,
securityGroupName: "eic_sg",
});
const eic = new CfnInstanceConnectEndpoint(this, "eic", {
subnetId: vpc.isolatedSubnets[0].subnetId,
securityGroupIds: [eicSg.securityGroupId],
});
- EC2 Instance Connect Endpoint 用のセキュリティグループ
- 全てのアウトバウンドを不許可
- EC2 Instance Connect Endpoint
- プライベートサブネットに配置
-
eic_sg
のセキュリティグループ割り当て
なお、EC2 Instance Connect Endpoint は VPC 内に 1 つしか作成できません。
プライベートサブネットに構築した EC2 への接続のことを考えて、プライベートサブネットの方に作成しておきます。
EC2 の構築
リソースの作成
次に EC2 関連のリソースを作成していきます。
import { aws_ec2 as ec2, aws_iam as iam, CfnOutput } from "aws-cdk-lib";
~省略~
const ec2Role = new iam.Role(this, "ec2_role", {
assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName(
"AmazonSSMManagedInstanceCore"
),
],
});
const ec2Sg = new ec2.SecurityGroup(this, "ec2_sg", {
vpc,
allowAllOutbound: true,
securityGroupName: "ec2_sg",
});
eicSg.connections.allowTo(ec2Sg, ec2.Port.tcp(22));
ec2Sg.connections.allowFrom(eicSg, ec2.Port.tcp(22));
ec2Sg.connections.allowFromAnyIpv4(ec2.Port.tcp(80));
const ec2Instance = new ec2.Instance(this, "ec2_instance", {
vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
role: ec2Role,
securityGroup: ec2Sg,
instanceName: "ec2_instance",
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T3,
ec2.InstanceSize.MICRO
),
machineImage: new ec2.AmazonLinuxImage({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2023,
}),
associatePublicIpAddress: true,
});
new CfnOutput(this, "ec2_instance_ip", {
value: ec2Instance.instancePublicIp,
});
new CfnOutput(this, "ec2 EIC connection command", {
value: `aws ec2-instance-connect ssh --instance-id ${ec2Instance.instanceId} --connection-type eice`,
});
- IAM ロール作成
- セッションマネージャー用に、
AmazonSSMManagedInstanceCore
ポリシーを付与。
- セッションマネージャー用に、
- EC2 のセキュリティグループ作成
-
eic_sg
からの、22 番ポートを解放。 - 全ての IP からの、80 番ポートを解放
-
- EIC のセキュリティグループ
-
ec2_sg
への 22 番ポートを解放。
-
- EC2
- AmazonLinux 2023 、t3.micro
- パブリック IP 設定
-
ec2_sg
、ec2_role
設定
CDK ではCfnOutput
を利用することで、CloudFormation のOutputs
のように値を出力することができます。
本コードでは、EC2 のパブリック IP アドレスとEC2 Instance Connect Endpoint
接続用のコマンドを出力するようにしています。
CDK Deploy
では、デプロイしてみましょう。
cdk deploy
正常にデプロイできた場合、CfnOutput
で定義した値が出力されているはずです。
Outputs:
CdkLaravelStack.ec2EICconnectioncommand = aws ec2-instance-connect ssh --instance-id <instanceId> --connection-type eice
CdkLaravelStack.ec2instanceip = <パブリックIP>
上記のCdkLaravelStack.ec2EICconnectioncommand
に出力されたコマンドをコピーして、EC2 に接続してみましょう。
aws ec2-instance-connect ssh --instance-id <instanceId> --connection-type eice
以下の画面が出力されれば、接続成功です。
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
[ec2-user@ip-10-0-0-95 ~]$
Laravel の構築
パッケージのインストール
構築に必要なパッケージをインストールしていきます。
sudo dnf upgrade --releasever=latest
dnf install -y php httpd mariadb105 php-mysqli
PHP と MySQL がインストールされていることを確認します
- PHP のインストール確認
$ php -v
PHP 8.2.15 (cli) (built: Jan 16 2024 12:19:32) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.2.15, Copyright (c) Zend Technologies
with Zend OPcache v8.2.15, Copyright (c), by Zend Technologies
- MySQL のインストール確認
$ mysql -V
mysql Ver 15.1 Distrib 10.5.23-MariaDB, for Linux (x86_64) using EditLine wrapper
Apache のインストール、起動
Apache を起動させ、自動起動を有効にします。
sudo systemctl start httpd
sudo systemctl enable httpd
ステータスがActive
になっていたら、起動成功です。
$ sudo systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/system/httpd.service.d
└─php-fpm.conf
Active: active (running) since Fri 2024-05-03 05:18:53 UTC; 56s ago
ここで、EC2 インスタンスに 80 ポートでアクセスできるか確認してみます。
http://<EC2インスタンスのIP>:80
Apache が起動しているかつ、セキュリティグループの設定に問題がなければ以下の画面が表示されるはずです。
Composer のインストール
Laravel をインストールするために、composer をインストールします。
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
composer のインストール確認
$ composer -V
Composer version 2.7.4 2024-04-22 21:17:03
PHP version 8.2.15 (/usr/bin/php)
Run the "diagnose" command to get more detailed diagnostics output.
Laravel のインストール
まずはパーミッションの変更をします。
Laravel の環境構築が目的のため、権限の問題を取り除くために777
を設定します。
$ cd /var/www
$ sudo chmod 777 /var/www
Laravel のプロジェクトを作成します。
composer create-project laravel/laravel webapp
エラーがなければ問題ないです。
Apache の設定変更
デフォルトだと /var/www/html
を表示するようになっているので、Laravel 側を表示するように設定変更する。
$ sudo vi /etc/httpd/conf/httpd.conf
Laravel のディレクトリに修正する。
- DocumentRoot "/var/www/html"
+ DocumentRoot "/var/www/webapp/public"
#
# Relax access to content within /var/www.
#
- <Directory "/var/www">
+ <Directory "/var/www/webapp/public">
conf を修正したので、Apache をリロードする。
$ sudo systemctl reload httpd
Apache が Laravel 側のファイルなどを正常に読み込めるよう、権限を修正する。
$ sudo chown -R apache:apache /var/www/webapp
再度、EC2 インスタンスにアクセスしてみる。
Laravel の画面が表示されていることを確認する。
Aurora ServerlessV2 の構築
現在のままだと、データベースに接続していないのでphp artisan migrate
が実行できない。
そのため、Aurora ServerlessV2
を構築する。
import {
aws_ec2 as ec2,
aws_iam as iam,
CfnOutput,
aws_rds as rds,
} from "aws-cdk-lib";
~省略~
const auroraSg = new ec2.SecurityGroup(this, "aurora_sg", {
vpc,
allowAllOutbound: true,
securityGroupName: "aurora_sg",
});
auroraSg.connections.allowFrom(ec2Sg, ec2.Port.tcp(3306));
const auroraCluster = new rds.DatabaseCluster(this, "aurora_cluster", {
engine: rds.DatabaseClusterEngine.auroraMysql({
version: rds.AuroraMysqlEngineVersion.VER_3_06_0,
}),
vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
writer: rds.ClusterInstance.serverlessV2("writer"),
serverlessV2MaxCapacity: 1.0,
serverlessV2MinCapacity: 0.5,
securityGroups: [auroraSg],
defaultDatabaseName: "laravel",
});
auroraCluster.applyRemovalPolicy(RemovalPolicy.DESTROY);
new CfnOutput(this, "Aurora Cluster secretmanager", {
value: `aws secretsmanager get-secret-value --secret-id ${
auroraCluster.secret!.secretName
}`,
});
- Aurora 用のセキュリティグループ作成
- EC2 からの 3306 ポートのみ解放
- Aurora Serverless V2
- Aurora MySQL の 3.06 バージョン
- プライベートサブネットに配置
-
laravel
データベース作成 - Aurora の容量(ACU)を最大 1、最小 0.5 に設定
- CDK のリソース削除時に、DB を破棄する
なお、DB への接続情報などは Secret Manager に登録されます。Secret Manager から値を取得するため、CfnOutput
でシークレット名を取得しています。
CDK Deploy
デプロイします。
cdk deploy
正常にデプロイできた場合、次の値が出力されるはずです。
CdkLaravelStack.AuroraClustersecretmanager = aws secretsmanager get-secret-value --secret-id <secret-id>
この値をもとに、DB の各情報を取得しましょう。
aws secretsmanager get-secret-value --secret-id <secret-id>
{
"ARN": "...",
"Name": "...",
"VersionId": "...",
"SecretString": "{\"dbClusterIdentifier\":\"...\",\"password\":\"...\",\"dbname\":\"laravel\",\"engine\":\"mysql\",\"port\":3306,\"host\":\"...\",\"username\":\"admin\"}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": "..."
}
host、usrename、password の値を控えておきます。
Aurora への接続
再度、EC2 に接続しましょう。
aws ec2-instance-connect ssh --instance-id <instanceId> --connection-type eice
先ほど控えた値をもとに Aurora に接続します。
mysql -h <host> -P 3306 -u admin -p
以下のような表示がでれば、接続成功です。
MySQL [(none)]>
laravel のテーブル有無を確認します。
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| laravel |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.047 sec)
ちゃんと作成されていることが確認できました。
Laravel の DB 接続情報の変更
MySQL からexit
で抜け、EC2 の画面にもどります。
Laravel では.env
ファイルに、DB の設定を行うので、こちらのファイルを修正します。
DB_CONNECTION=mysql
DB_HOST=<host>
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=admin
DB_PASSWORD=<password>
設定ファイルを修正したので、config:cache
コマンドを実行します。
sudo php artisan config:cache
php artisan migrate
を実行してみます。
$ sudo php artisan migrate
INFO Preparing database.
Creating migration table ........................................................... 437.55ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ............................................... 873.25ms DONE
0001_01_01_000001_create_cache_table ............................................... 238.12ms DONE
0001_01_01_000002_create_jobs_table ................................................ 477.59ms DONE
特にエラーがでていないければ、migrate
成功です!
これで 、Amazon Linux2023 + Aurora Serverlessv2 の Laravel 環境を CDK で構築することができました。
お疲れ様でした。