この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
皆様こんにちは。
今回はCLIを利用して高可用性アーキテクトの構築をしていきます。
この記事ではCLIよりEC2の作成を行います。
このブログはCLIによるEC2の作成をする上での知識を記事としてまとめ再確認し、皆様と共有するため作成します。
1.高可用性アーキテクト構築目次
2.EC2とは
Amazon Elastic Compute Cloud (Amazon EC2) は、Amazon Web Service (AWS) クラウドでスケーラブルなコンピューティングキャパシティーを提供します。Amazon EC2 の使用により、ハードウェアに事前投資する必要がなくなり、アプリケーションをより速く開発およびデプロイできます。
引用:Amazon EC2 とは
今回は高可用性アーキテクトを構築していくうえで必要なサーバとしてEC2をマルチAZ配置で利用します。
類似サービスとして「Amazon Lightsail」のインスタンスなどがあげられます。
3.フロー図
マルチAZ配置で冗長化し、以下のフローで可用性を高めます。
- 障害が発生し、片方のインスタンスが利用不可になります。
- ALBを利用し処理をもう一つのインスタンスに肩代わりします。
4.EC2作成
EC2を作成する前に構築時に使用するSSHキーペアとユーザーデータ、EBSの設定ファイルを自前に設定します。
4-1.SSHキーペア作成
Amazon EC2 インスタンスへの接続時の身分証明に使用するSSHキーペアを作成します。
4-1-1.SSHキーペアとは
キーペアには、プライベートキーと公開キーを含んでおり、 Amazon EC2 インスタンスへの接続時の身分証明に使用する、セキュリティ認証情報のセットを構成しています。パブリックキーは、Amazon EC2 によりお客様のインスタンス内に保管されます。またプライベートキーは、お客様自身が保管します。Linux インスタンスの場合、プライベートキーにより、インスタンスへの安全な SSH 接続を可能にしています。
引用:Amazon EC2 のキーペアと Linux インスタンス
4-1-2キーペア作成
まずSSHキーペアを作成するために、[aws ec2 create-key-pair]コマンドを使用します。
使用するオプション | 設定値 | 説明 |
---|---|---|
--key-name | umemoto_kadai_1 | キーネームを入力 |
--query | ‘KeyMaterial’ | キーの内容を抽出 |
--output | text \ out-file -encoding ascii -filepath C:\key\umemoto_kadai_1.pem | 指定のパスにキーを作成 |
入力
aws ec2 create-key-pair `
--key-name umemoto_kadai_1 `
--query 'KeyMaterial' `
--output text | out-file -encoding ascii -filepath C:\key\umemoto_kadai_1.pem
出力なし
指定のパスに作成できていたら問題ないです。
4-2.ユーザーデータ作成
ユーザーデータを利用し、あらかじめ設定したコマンドを起動時に自動的に実行させます。
4-2-1.ユーザーデータとは
WordPressサーバー構築に使用するコマンドをまとめたユーザーデータを以下のように作成します。
WordPressは高可用性アーキテクトの検証のため導入します。
ユーザーデータを利用することにより、あらかじめ設定したコマンドを起動時に自動的に実行させることができます。(ユーザーデータについての概要はこちらを参照ください。)
4-2-2.ユーザーデータ設定
今回コマンドでパス指定するものは全て絶対パスで指定しています。(詳しいパスの指定方法についてはこちら)
ファイル名:user-data.txt
#!/bin/bash
sudo yum install httpd -y
sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2
sudo yum install -y amazon-efs-utils
sudo mount -t efs -o tls fs-xxxxx:/ /var/www/html/
echo 'fs-xxxxx:/ /var/www/html efs tls,_netdev 0 0' | sudo tee -a /etc/fstab
sudo wget -P /tmp https://wordpress.org/latest.zip
sudo unzip /tmp/latest.zip -d /tmp
sudo mv /tmp/wordpress/* /var/www/html/
sudo chown -R apache /var/www
sudo chgrp -R apache /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
sudo systemctl enable httpd.service
sudo systemctl start httpd.service
wget -P /tmp https://s3.ap-northeast-3.amazonaws.com/amazoncloudwatch-agent-ap-northeast-3/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
sudo rpm -U /tmp/amazon-cloudwatch-agent.rpm
-
2行目
#! /bin/bash
は、
「#!」で始まるジバンと呼ばれる文字列は、このシェルスクリプトはbashを利用して解釈/実行されるという宣言をしています。 -
3行目
sudo yum install httpd -y
は、
appache httpdのインストールコマンドです。-y
は全ての問い合わせに「yes」で応答するオプションです。
-
4行目
sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2
は、
Amazon Linux 2のExtras Libraryとよばれるパッケージ群(トピックといいます)からLamp環境に必要なものをまとめてインストールしています。 -
5行目
sudo yum install -y amazon-efs-utils
は、
EFSマウントヘルパーのインストールです。-y
は全ての問い合わせに「yes」で応答するオプションです。
-
6行目
sudo mount -t efs -o tls fs-xxxxx:/ /var/www/html/
は、
EFSのマウントコマンドです。fs-xxxxxは自分のefsIDを設定します。-o tls
はtlsを利用して暗号化するコマンドです。
-
7行目
echo 'fs-xxxxx:/ /var/www/html efs tls,_netdev 0 0' | sudo tee -a /etc/fstab
について、
インスタンスの再起動時に、EFSを自動マウントするためのコマンドです。なので、fs-xxxxxを自分のefsIDに書き換える必要があります。- 「/etc/fstab」ファイルは、マウントするファイルシステムの情報を記述するファイルです。なので、
fs-xxxxx:/ /var/www/html efs tls,_netdev 0 0
を書き込む事で起動時に自動マウント設定を行えます。 sudo echo
で直接書き込もうとするとリダイレクト処理が挟まって一般ユーザー権限になり、Permission deniedエラーが発生します。
- 「/etc/fstab」ファイルは、マウントするファイルシステムの情報を記述するファイルです。なので、
-
8行目
sudo wget -P /tmp https://wordpress.org/latest.zip
について、
Wordpressをダウンロードします。-P
で保存先にtmpディレクトリを指定しています。tmp内のファイルやフォルダは10日経過又はインスタンス再起動で自動的に削除されます。
-
9行目
sudo unzip /tmp/latest.zip -d /tmp
について、
ダウンロードしたWordpressを解凍します。-d
で解凍先にtmpディレクトリを指定しています。
-
10行目
sudo mv /tmp/wordpress/* /var/www/html/
について、
apacheの公開領域(/var/www/html/)にwordpressファイルを移動させています。 -
11~15行目は権限回りの付与です。
こちらを設定しないとWordpressインストールプロセス中にconfig.phpファイルを自動で作成することができません。 -
16行目
sudo systemctl enable httpd.service
について、
apacheの自動起動を有効にするコマンドです。 -
17行目
sudo systemctl start httpd.service
について、
apacheの起動コマンドです。 -
20,21行目
wget -P /tmp https://s3.ap-northeast-3.amazonaws.com/amazoncloudwatch-agent-ap-northeast-3/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm,sudo rpm -U /tmp/amazon-cloudwatch-agent.rpm
CloudWatchAgentをダウンロードし、インストールしています。
4-3.EBS設定
今回EBSは--block-device-mappings
オプションで直接設定し作成します。
4-3-1.EBSとは
Amazon Elastic Block Store (Amazon EBS) は、EC2 インスタンスで使用するためのブロックレベルのストレージボリュームを提供します。EBS ボリュームの動作は、未初期化のブロックデバイスに似ています。これらのボリュームは、デバイスとしてインスタンスにマウントできます。
引用:Amazon Elastic Block Store (Amazon EBS)
4-3-2.EBS設定内容
--block-device-mappings
オプションは以下の設定でいきます。
--block-device-mappings `
"DeviceName=/dev/xvda, `
Ebs={DeleteOnTermination=true,VolumeType=gp3,VolumeSize=8, `
Encrypted=true,KmsKeyId=xxxxx-xxxx-xxxx-xxxx-xxxxx}"
項目 | 設定値 | 説明 |
---|---|---|
DeviceName | /dev/xvda | ルートデバイス名の入力 |
DeleteOnTermination | true | EC2終了時に削除 |
VolumeType | gp3 | ボリュームタイプ |
VolumeSize | 8 | ボリュームサイズ(GiB) |
Encrypted | true | 暗号化の有効化 |
KmsKeyId | xxxxx-xxxx-xxxx-xxxx-xxxxx | 作成したKMSのid |
4-4.EC2インスタンスの作成
ここまで出来たら、いよいよEC2の作成をします。
作成をするために、[aws ec2 run-instances]コマンドを使用します。
使用するオプション | 設定値 | 説明 |
---|---|---|
--image-id | ami-0cbec04a61be382d9 | 使用するAMIのIDを入力 |
--block-device-mappings | "DeviceName=/dev/xvda,Ebs={DeleteOnTermination=true, VolumeType=gp3,VolumeSize=8, Encrypted=true, KmsKeyId=xxxxx-xxxx-xxxx-xxxx-xxxxx}" |
先ほどのEBSの設定で入力 |
--count | 1 | 使用するEI アクセラレータ数を指定 |
--instance-type | t2.micro | 使用するインスタンスタイプを指定 |
--key-name | umemoto_kadai_1 | 先ほど作成したキーネームを入力 |
--security-group-ids | sg-xxxxx | 前回作成したEC2用のSGのIDを入力 |
--subnet-id | subnet-xxxxx,subnet-xxxxx | 使用する二つのパブリックサブネットを入力 |
--private-ip-address | 10.0.1.10,10.0.2.20 | 前回の構成図に設定したIPを入力 |
--iam-instance-profile | Name=umemoto-wordpress-profile | 前回作成したインスタンスプロファイルの名前を入力 |
--capacity-reservation-specification | CapacityReservationPreference=none | キャパシティの予約をオフに |
--user-data | file://C:\ec2\user-data.txt | 先ほど作成したユーザーデータのパスを入力 |
--tag-specifications | "ResourceType=instance, Tags= [{Key=Name,Value=umemoto-wordpress-1}]" "ResourceType=volume, Tags= [{Key=Name,Value=umemoto-wordpress-1}]", "ResourceType=instance, Tags= [{Key=Name,Value=umemoto-wordpress-2}]" "ResourceType=volume, Tags= [{Key=Name,Value=umemoto-wordpress-2}]" |
タグを設定 |
4-4-1.--dry-runオプションによる検証
今回はオプションが多いため作成のリクエストが成功するかの検証のため最初に--dry-run
オプションを付けて実行してみます。
入力(構成図でcidr 10.0.1.10のインスタンスの場合)
aws ec2 run-instances `
--dry-run `
--image-id ami-0cbec04a61be382d9 `
--block-device-mappings `
"DeviceName=/dev/xvda, `
Ebs= {DeleteOnTermination=true,VolumeType=gp3,VolumeSize=8, `
Encrypted=true,KmsKeyId=xxxxx-xxxx-xxxx-xxxx-xxxxx}" `
--count 1 --instance-type t2.micro `
--key-name umemoto_kadai_1 `
--security-group-ids sg-xxxxx `
--subnet-id subnet-xxxxx `
--private-ip-address 10.0.1.10 `
--iam-instance-profile Name=umemoto-wordpress-profile `
--capacity-reservation-specification CapacityReservationPreference=none `
--user-data file://C:\ec2\user-data.txt `
--tag-specifications "ResourceType=instance, Tags=[{Key=Name,Value=umemoto-wordpress-1}]"
"ResourceType=volume, Tags=[{Key=Name,Value=umemoto-wordpress-1}]"
出力
An error occurred (DryRunOperation) when calling the RunInstances
operation: Request would have succeeded, but DryRun flag is set.
作成のリクエストは成功するはずでしたが、dry-runが設定されているため実際にはインスタンス作成の作成は行われていません。
4-4-2.EC2インスタンス作成
コマンドには問題がないことを確認できたので--dry-run
オプションを外して再度実行してみましょう。
入力(構成図でcidr 10.0.1.10のインスタンスの場合)
aws ec2 run-instances `
--image-id ami-0cbec04a61be382d9 `
--block-device-mappings `
"DeviceName=/dev/xvda, `
Ebs= {DeleteOnTermination=true,VolumeType=gp3,VolumeSize=8, `
Encrypted=true,KmsKeyId=xxxxx-xxxx-xxxx-xxxx-xxxxx}" `
--count 1 --instance-type t2.micro `
--key-name umemoto_kadai_1 `
--security-group-ids sg-xxxxx `
--subnet-id subnet-xxxxx `
--private-ip-address 10.0.1.10 `
--iam-instance-profile Name=umemoto-wordpress-profile `
--capacity-reservation-specification CapacityReservationPreference=none `
--user-data file://C:\ec2\user-data.txt `
--tag-specifications "ResourceType=instance, Tags=[{Key=Name,Value=umemoto-wordpress-1}]"
"ResourceType=volume, Tags=[{Key=Name,Value=umemoto-wordpress-1}]"
出力
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-0cbec04a61be382d9",
"InstanceId": "i-xxxxx",
"InstanceType": "t2.micro",
"KeyName": "umemoto_kadai_1",
"LaunchTime": "2022-05-10T06:12:07+00:00",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "ap-northeast-2a",
"GroupName": "",
"Tenancy": "default"
},
"PrivateDnsName": "ip-10-0-1-10.ap-northeast-2.compute.internal",
"PrivateIpAddress": "10.0.1.10",
"ProductCodes": [],
"PublicDnsName": "",
"State": {
"Code": 0,
"Name": "pending"
},
"StateTransitionReason": "",
"SubnetId": "subnet-xxxxx",
"VpcId": "vpc-xxxxx",
"Architecture": "x86_64",
"BlockDeviceMappings": [],
"ClientToken": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
"EbsOptimized": false,
"EnaSupport": true,
"Hypervisor": "xen",
"IamInstanceProfile": {
"Arn": "arn:aws:iam::xxxxx:instance-profile/umemoto-wordpress-profile",
"Id": "xxxxx"
},
"NetworkInterfaces": [
{
"Attachment": {
"AttachTime": "2022-05-10T06:12:07+00:00",
"AttachmentId": "eni-attach-xxxxx",
"DeleteOnTermination": true,
"DeviceIndex": 0,
"Status": "attaching",
"NetworkCardIndex": 0
},
"Description": "",
"Groups": [
{
"GroupName": "umemoto_SG_EC2",
"GroupId": "sg-xxxxx"
}
],
"Ipv6Addresses": [],
"MacAddress": "02:43:c9:fd:01:ae",
"NetworkInterfaceId": "eni-xxxxx",
"OwnerId": "xxxxx",
"PrivateDnsName": "ip-10-0-1-10.ap-northeast-2.compute.internal",
"PrivateIpAddress": "10.0.1.10",
"PrivateIpAddresses": [
{
"Primary": true,
"PrivateDnsName": "ip-10-0-1-10.ap-northeast-2.compute.internal",
"PrivateIpAddress": "10.0.1.10"
}
],
"SourceDestCheck": true,
"Status": "in-use",
"SubnetId": "subnet-xxxxx",
"VpcId": "vpc-xxxxx",
"InterfaceType": "interface"
}
],
"RootDeviceName": "/dev/xvda",
"RootDeviceType": "ebs",
"SecurityGroups": [
{
"GroupName": "umemoto_SG_EC2",
"GroupId": "sg-xxxxx"
}
],
"SourceDestCheck": true,
"StateReason": {
"Code": "pending",
"Message": "pending"
},
"Tags": [
{
"Key": "Name",
"Value": "umemoto-wordpress-1"
}
],
"VirtualizationType": "hvm",
"CpuOptions": {
"CoreCount": 1,
"ThreadsPerCore": 1
},
"CapacityReservationSpecification": {
"CapacityReservationPreference": "none"
},
"MetadataOptions": {
"State": "pending",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
},
"EnclaveOptions": {
"Enabled": false
},
"PrivateDnsNameOptions": {
"HostnameType": "ip-name",
"EnableResourceNameDnsARecord": false,
"EnableResourceNameDnsAAAARecord": false
},
"MaintenanceOptions": {
"AutoRecovery": "default"
}
}
],
"OwnerId": "xxxxx",
"ReservationId": "r-xxxxx"
}
EC2インスタンスを作成できました。
二つ目のインスタンスも上記と同様の手順で作成します。
これでEC2の作成の説明を終わります。
5.検証
5-1.EC2検証
EC2の作成ができましたら実際にSSHで接続しhttpdが起動できているかと、Wordpressがダウンロードできているかの確認を行います。
①SSHで接続出来たら以下のコマンドでhttpdの起動を確認します。
systemctl status httpd.service
出力
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Drop-In: /usr/lib/systemd/system/httpd.service.d
mqphp-fpm.conf
Active: active (running) since Mon 2022-05-23 09:11:02 UTC; 7min ago
Docs: man:httpd.service(8)
Main PID: 3253 (httpd)
Status: "Total requests: 24; Idle/Busy workers 55/44;Requests/sec: 0.0547; Bytes served/sec: 31 B/sec"
CGroup: /system.slice/httpd.service
tq3253 /usr/sbin/httpd -DFOREGROUND
tq3270 /usr/sbin/httpd -DFOREGROUND
tq3271 /usr/sbin/httpd -DFOREGROUND
tq3272 /usr/sbin/httpd -DFOREGROUND
tq3273 /usr/sbin/httpd -DFOREGROUND
tq3274 /usr/sbin/httpd -DFOREGROUND
tq3346 /usr/sbin/httpd -DFOREGROUND
tq3355 /usr/sbin/httpd -DFOREGROUND
tq3403 /usr/sbin/httpd -DFOREGROUND
mq3413 /usr/sbin/httpd -DFOREGROUND
May 23 09:11:02 ip-10-0-1-10.ap-northeast-2.compute.internal systemd[1]: Starting The Apache HTTP Server...
May 23 09:11:02 ip-10-0-1-10.ap-northeast-2.compute.internal systemd[1]: Started The Apache HTTP Server.
起動を確認できました。
②次に以下のコマンドを使用してwordpressのダウンロードを確認します。
cd /var/www/html
ls -m
出力
index.php, license.txt, readme.html, wp-activate.php, wp-admin, wp-blog-header.php, wp-comments-post.php, wp-config.php, wp-config-sample.php, wp-content,
wp-cron.php, wp-includes, wp-links-opml.php, wp-load.php, wp-login.php, wp-mail.php, wp-settings.php, wp-signup.php, wp-trackback.php, xmlrpc.php
必要なものがダウンロードされていることを確認できました。
③より詳しいユーザデータの実行ログは以下のコマンドで取得できます。
sudo cat /var/log/cloud-init-output.log
出力は非常に長いため今回は省略します。
ユーザデータはcloud-initを介して実行するので、cloud-init-output.logからユーザデータの実行ログを取得できます。
5-2.EFS検証
EFSのブログで検証しています。
5-3.RDS検証
RDSのブログで検証しています。
6.感想
EC2の作成コマンドはオプションが多く大変でしたがオプション含め一つのコマンドでEC2を作成できるのは楽しいと感じました。
7.参照
AWS CLI Command Reference – ec2
https://docs.aws.amazon.com/cli/latest/reference/ec2/index.html#cli-aws-ec2