0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ひろ亭Advent Calendar 2021

Day 16

AWS CLIで Web サイトを構築、管理、運用する(16日目)

Last updated at Posted at 2021-12-15

16日目!

今回は、ついに EC2 を立ち上げます。
14日目、15日目はこのためにありました・・・!

16日目の要約

仮想マシンを立ち上げて、動的なコンテンツを表示できるようにするよ!

AWS CLI の準備

このあたりをみて、好きなバージョンとお使いのOSにあった環境設定をしてくださいね。
なんなら、 AWS CloudShell で実行するのも楽でよいと思います。
この記事シリーズは、AWS CloudShell で実行し、実行例を載せています。

バージョン1
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv1.html

バージョン2
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html

概要

最新の AMI を使って、EC2インスタンスを立ち上げます。さらに、名前解決できるようにしてCloudFrontのディストリビューションとしても登録するよ!

さあ、やってみよう!

最新の Amazon Linux 2 の AMI ID を確認する

EC2 インスタンスを作成、起動するには、Amazon Machine Image(AMI)が必要です。どの AMI を使用するのか特定するために、 AMI ID を確認します。

最新の Amazon Linux 2 の AMI ID を特定するには、Simple Systems Manager のコマンドである、 ssm get-parameter を実行します。

aws ssm get-parameter --name /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 \

正常に実行できると、以下のような json が返るので、 Value の値を確認します。
この値が 最新の AMI ID です。

{
    "Parameter": {
        "Name": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
        "Type": "String",
        "Value": "ami-0abaa5b0faf689830",
        "Version": 55,
        "LastModifiedDate": "2021-12-02T04:23:22.207000+00:00",
        "ARN": "arn:aws:ssm:ap-northeast-1::parameter/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
        "DataType": "text"
    }
}

EC2 インスタンスを起動する!

AMI ID の特定ができたら、次は、EC2 インスタンスを起動します。
以下の情報が必要になるので、確認をしてください。

  • AMI ID
  • サブネット ID
  • セキュリティグループ ID
  • Route53 のホスティッドゾーン ID
  • Route53 に登録したいレコード名(ホスト名+これまでに設定したドメイン名)
  • インスタンスプロファイル名

まずは、EC2 インスタンスが起動時に実行するユーザーデータを作成します。
流れとしては、インスタンスメタデータにアクセスし、インスタンス側からパブリックIPv4アドレスとインスタンスIDを取得します。
こうすることにより、起動時に動的に情報を取得・更新、Route53 へのレコード登録ができるようになります。

以下を参考にして、お好みのテキストエディタで作成してください。

uesrdata.sh
#!/bin/bash
HOSTED_ZONE_ID=<Route53 のホスティッドゾーン ID>
RECORD_NAME=<登録したいホスト名>.<ドメイン名>

TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
INSTANCE_ID=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id`
IP_ADDRESS=`curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-ipv4`

yum update -y
yum install -y httpd 
systemctl start httpd
systemctl enable httpd
usermod -a -G apache ec2-user
mkdir -p /var/www/html/ec2
chown -R ec2-user:apache /var/www
chmod 2775 /var/www
find /var/www -type d -exec chmod 2775 {} \;
find /var/www -type f -exec chmod 0664 {} \;
echo "<HTML><HEAD><TITLE>from EC2</TITLE><BODY>This is ${INSTANCE_ID}.</BODY></HTML>" > /var/www/html/ec2/index.html
aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} \
--change-batch "{\"Changes\": [ { \"Action\": \"UPSERT\", \"ResourceRecordSet\": { \"Name\": \"${RECORD_NAME}.\", \"Type\": \"A\", \"TTL\": 3600, \"ResourceRecords\": [{\"Value\": \"${IP_ADDRESS}\"}]}}]}"

ユーザーデータのファイルが作成できたら、以下を参考にして、 ec2 run-instances コマンドを実行して EC2 インスタンスを起動します。

AMI_ID=<AMI の ID>
SUBNET_ID=<サブネットのID>
SECURITY_GROUP_ID=<セキュリティグループのID>
INSTANCE_PROFILE=<インスタンスプロファイル名>

aws ec2 run-instances \
    --image-id ${AMI_ID} \
    --instance-type t2.micro \
    --subnet-id ${SUBNET_ID} \
    --iam-instance-profile "Name=${INSTANCE_PROFILE}" \
    --security-group-ids ${SECURITY_GROUP_ID} \
    --user-data file://userdata.sh

正常に実行・起動できると json が返りますが長いのでこの記事では割愛します。
念のため、InstanceId の値を確認してください。

ちなみに、 ec2 run-instances コマンドの --iam-instance-profile オプションは NameArn を指定する必要があるような記載がマニュアルにあります。
しかし、実際に両方指定して実行すると、以下のようなエラーが返りますご注意ください。

An error occurred (InvalidParameterCombination) when calling the RunInstances operation: The parameter 'iamInstanceProfile.name' may not be used in combination with 'iamInstanceProfile.arn'

これで、EC2 インスタンスが起動しました。
起動出来たら動作確認として、 curl コマンドでアクセスしたくなりますが、セキュリティグループのインバウンドルールに入っているのは CloudFront からのIPアドレス群のみです。
そのため、動作確認はディストリビューションの設定を変えてからです。

CloudFront のディストリビューションに EC2 をオリジンとして登録する

これまで何回も実施したディストリビューションの変更手順と同じです。
復習を兼ねてみていきましょう。

  1. cloudfront get-distribution-config コマンドで現状の設定を取得する
  2. ETag の値を確認する
  3. 取得した json ファイルに対して、設定変更を加える
  4. cloudfront update-distribution コマンドを実行して更新する

ディストリビューションの現状の設定を確認する

cloudfront get-distribution-config コマンドを実行して、現在のディストリビューションの設定を出力します。

aws cloudfront get-distribution-config --id <CloudFront の Distribution ID> > distribution_ec2_tmp.json

次に、必要な部分だけ抽出して更新用の元ファイルにします。jq コマンドを使うので、必要に応じてインストールしてください。AWS CloudShell であれば標準でインストール済みです。

cat distribution_ec2_tmp.json | jq .DistributionConfig > distribution_ec2.json

ETag の値を確認する

ディストリビューションの設定変更時に必要になる、 ETag の値を確認します。

cat distribution_ec2_tmp.json | grep ETag

以下のように出力されます。

    "ETag": "**************",

json ファイルを編集する

以下を編集します。

  • Origins
  • CacheBehaviors

Origins

取得してきたディストリビューションには、S3バケットをオリジンとする設定が入っていると思われます。
そのため、2つ目として、EC2 インスタンスをオリジンとして登録します。

  • Quantity の値を2にします
  • 以下の内容を Items のS3 バケットをオリジンとする定義の前に書き込みます。
      {
        "Id": "<Route53 に登録したEC2のレコード>",
        "DomainName": "<Route53 に登録したEC2のレコード>",
        "OriginPath": "",
        "CustomHeaders": {
          "Quantity": 0
        },
        "CustomOriginConfig": {
          "HTTPPort": 80,
          "HTTPSPort": 443,
          "OriginProtocolPolicy": "http-only",
          "OriginSslProtocols": {
            "Quantity": 3,
            "Items": [
              "TLSv1",
              "TLSv1.1",
              "TLSv1.2"
            ]
          },
          "OriginReadTimeout": 30,
          "OriginKeepaliveTimeout": 5
        },
        "ConnectionAttempts": 3,
        "ConnectionTimeout": 10,
        "OriginShield": {
          "Enabled": false
        }
      },

CacheBehaviors

次にキャッシュビヘイビアの設定を行います。
今回は、キャッシュのTTLをゼロにします。
EC2 インスタンスのユーザーデータの内容を確認された方ならこれでピンとくるかもしれませんが、起動時にインスタンス ID を index.html に書き込んでいます。
この index.html をキャッシュに持ってしまうと、EC2 インスタンスが入れ替わった際にも TTL が切れるまで古いインスタンス ID の情報が返ってしまいます。
それを防ぐために、敢えてゼロとしました。
ちなみにデフォルトの TTL は86,400秒、つまり、24時間です(3,600 秒 * 24時間)。最大TTLは、31,536,000秒なので1年が設定されています。

  • 以下の内容を CacheBehaviors の定義を編集します。
編集前
  "CacheBehaviors": {
     "Quantity": 0
   },
編集後
  "CacheBehaviors": {
    "Quantity": 1,
    "Items": [
      {
        "PathPattern": "ec2/*",
        "TargetOriginId": "<Route53 に登録したEC2のレコード>",
        "TrustedSigners": {
          "Enabled": false,
          "Quantity": 0
        },
        "TrustedKeyGroups": {
          "Enabled": false,
          "Quantity": 0
        },
        "ViewerProtocolPolicy": "allow-all",
        "AllowedMethods": {
          "Quantity": 2,
          "Items": [
            "HEAD",
            "GET"
          ],
          "CachedMethods": {
            "Quantity": 2,
            "Items": [
              "HEAD",
              "GET"
            ]
          }
        },
        "SmoothStreaming": false,
        "Compress": true,
        "LambdaFunctionAssociations": {
          "Quantity": 0
        },
        "FunctionAssociations": {
          "Quantity": 0
        },
        "FieldLevelEncryptionId": "",
        "ForwardedValues": {
          "QueryString": false,
          "Cookies": {
            "Forward": "none"
          },
          "Headers": {
            "Quantity": 0
          },
          "QueryStringCacheKeys": {
            "Quantity": 0
          }
        },
        "MinTTL": 0,
        "DefaultTTL": 0,
        "MaxTTL": 0
      }
    ]
  },

仕上げ

以下のように頭と末尾に情報を入力します。
1行目に波括弧({)があるので、その2行目に対して、 “DistributionConfig”: { を追加します。

distributionconfig.json_頭
{
"DistributionConfig": {
  "CallerReference": 

(省略)

次に末尾です。

distributionconfig.json_末尾
(省略)
  "WebACLId": "",
  "HttpVersion": "http2",
  "IsIPV6Enabled": true
 }
}   <-- これを追加する

末尾に閉じ波括弧(})を追加します。

ディストリビューションの設定を更新する

更新用のファイルが準備できたら、cloudfront update-distribution コマンドを実行して、設定変更を行います。

aws cloudfront update-distribution --id <CloudFront Distribution ID> --cli-input-json file://distribution_ec2.json --if-match 確認したETag の値

コマンド実行に成功すると、Distribution の内容が記された json が返されます。
案の定、長いので割愛します💦

動作確認

設定変更ができたので、以下の様に curl を実行してみましょう。

curl https://<CloudFrontのドメイン名>/ec2/index.html

すると、以下の様に インスタンスID が入った HTML が返ってきます。
返ってこない場合は、WAF のアノニマスIPアドレスのルールが当たっている可能性があります。
その場合はルールを一時的に解除するか、ローカルのターミナルなどでご確認ください。

<HTML><HEAD><TITLE>from EC2</TITLE><BODY>This is (インスタンスID).</BODY></HTML>

まとめ

準備編が2回あり、ついに EC2 インスタンスが起動しました!
さて、明日は、現在1台の EC2 インスタンスの可用性を挙げるべく、冗長構成にしていきます。

お楽しみに♪

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?