Web開発のしおりRepository

Webエンジニアリング関連の技術記事を掲載させていただいております。

コマンド1発でAWSに極小構成のWebサーバー(SSL/TLS対応済み)を構築したい

「とりあえず動けばいい。お金払いたくない。ドメインとかSSL証明書設定めんどい。ロードバランサーとかいらん。」という忙しくてケチな人向け。

なにする

SSL/TLS対応済みのWebサーバーの極小の構成をささっと作ります。CloudFormationを使います。

大体の流れをつかめばDockerなどとの組み合わせで、コマンド1発でWebサーバーとそのインフラを構築、削除できます。

今回書いたコード等:

GitHub - ponsea/aws-minimal-webserver: Minimal Web server with SSL/TLS on AWS

インフラ仕様

  • サーバーはEC2インスタンス1個のみ
  • WebサーバーのURLのホスト名は適当になるがHTTPSで接続できる。(自前でドメインや証明書の用意をする必要無し)
    • このようなURLになる => https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/
  • サーバーにSSHできる
  • 課金は 任意のEC2インスタンスの料金 + Route53のホストゾーン(月50円) + CloudMapのNamespace (月10円) ほど
    • 料金面は適宜、公式ページでご確認ください

インフラ構成

最終的なインフラ構成です。

f:id:ponsea:20200905135551p:plain
インフラ構成

API GatewayVPCリンクと、プライベート統合機能を用いてリクエストをEC2にバイパスします。 Cloud MapはApiGatewayがEC2インスタンスIPアドレス/ポート番号を解決するために用います。

前提

  • アカウント登録してAWS CLIをインストール済み
  • 前述のインフラ構成を構築する権限がある
  • EC2のキーペアを1個作っている

今回はCloudFormationを使います。CloudFormationとは端的に言うと、前述のインフラ構成を定義したファイル(yamlまたはjson形式)を用意して実行すると、そのインフラ構成を実際に構築してくれる優れものです。

以下に今回のCloudFormationのテンプレートファイル(インフラ構成を定義したファイル)があります。

GitHub - ponsea/aws-minimal-webserver: Minimal Web server with SSL/TLS on AWS

template.yaml がインフラ構成の定義ファイルです。

template.yamlの中ではすでに、自動でDockerのhttpdイメージが80番ポートで実行される様に設定されています。(詳細は後述)

docker run -d -p 80:80 httpd

コマンド1発でインフラを構築する

template.yamlがあるディレクトリで以下のコマンドを実行します。すると実際にインフラ構成が構築されます。

aws cloudformation create-stack \
  --stack-name minimal-webserver \ 任意のスタック名 (実際に作成されるAWSリソースの総称のようなもの)
  --template-body file://template.yaml \
  --parameters \
      ParameterKey=Ec2InstanceType,ParameterValue=t2.micro \ インスタンスタイプはお好みで(t2.microの部分)
      ParameterKey=SshKeyName,ParameterValue=<YOUR SSH KEY NAME> \ 予め作っておいたEC2のSSHキーペア名を指定
      ParameterKey=SshLocation,ParameterValue=<YOUR SSH LOCATION> SSH元のIPをx.x.x.x/x形式で指定し制限することをお勧めします。省略すれば0.0.0.0/0(制限なし)となります。

構築の様子はAWSのCloudFormationのコンソールで確認できます。ステータスがCREATE_COMPLETEになれば構築完了です。

構築が完了したあと、EC2インスタンスのパブリックIPとWebサーバーのURL(エンドポイント)を確認します。

aws cloudformation describe-stacks --stack-name minimal-webserver

{
    "Stacks": [
        {
            ...

            "StackStatus": "CREATE_COMPLETE"

            ...

            "Outputs": [
                { 
                    "OutputKey": "ApiGatewayUrl",
                    ↓ WebサーバーのURL
                    "OutputValue": "https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/",
                    "Description": "API Gateway endpoint URL for $default stage"
                },
                {
                    "OutputKey": "Ec2InstancePublicIp",
                    ↓ EC2 インスタンスのパブリックIP
                    "OutputValue": "xxx.xxx.xxx.xxx",
                    "Description": "EC2 Instance Public IP"
                }
            ],

            ...
    ]
}

"OutputValue": "https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/", のURLにアクセスすれば、Webページが見れます。

現状ではDockerのhttpdイメージの「It works!」というページが表示されるはずです。

SSH接続したい場合

ssh -i "/path/to/your-ssh-key.pem" ec2-user@<YOUR EC2 PUBLIC IP>

全部全部まとめて削除したい場合:

aws cloudformation delete-stack --stack-name minimal-webserver

template.yaml 分析

今回事前に用意したtemplate.yamlで定義したEC2インスタンスは、予めDocker, docker-compose, gitをインストールし、Dockerのhttpdイメージを実行するスクリプトを埋め込んでいます。このスクリプトはEC2インスタンスの初回起動時に実行されます。

      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          # docker, gitインストール
          yum install -y docker git
          # docker-composeインストール
          curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
          chmod +x /usr/local/bin/docker-compose
          systemctl start docker # Dockerデーモン起動
          systemctl enable docker # Dockerデーモン自動起動設定
          usermod -a -G docker ec2-user # dockerコマンドをec2-userで実行できる様に
          docker run -d -p 80:80 httpd # httpdイメージを実行

aws-minimal-webserver/template.yaml at master · ponsea/aws-minimal-webserver · GitHub

用途に合わせて、ここでDockerのコンテナ構成を定義すれば、すぐにシングルノードの小さいWebサービス建てれそうですね。

CloudFormation便利!