20201104のAWSに関する記事は18件です。

DynamoDB のテーブル設計をしてみた

はじめに

Amplify のチュートリアルを触ってみて、その中で一番難しい(ん?ってなった)のは DynamoDB だったので、ドキュメントなどを見ながら、DynamoDB ではどういう風にテーブル設計すれば良いのか考えてみました。1

何かのコンセプトを学ぶ時は、縛りプレイをして苦しむのが良いというのが持論です。

DynamoDB のドキュメント曰く「設計が優れたアプリケーションでは、必要なテーブルは 1 つのみです。」らしいので、テーブル1つ縛りで縛りプレイすることにしました。 2

後は、ドキュメントを読んでいるとスキャンしたら負け、フィルタ使ったら負けみたいな雰囲気があるので、スキャンやフィルタも禁じることにします。

想定するアプリケーション

イベントを管理するアプリケーションを想定して設計してみます。

DynamoDB でリレーショナルデータをモデル化するための最初のステップ や、AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern を参考に、まずはアクセスパターンを分析することにしました。

ドキュメントに

 DynamoDB の場合は対照的に、答えが必要な質問が分かるまで、スキーマの設計を開始しないでください。ビジネス上の問題とアプリケーションのユースケースを理解することが不可欠です。

と記載がある通り、DynamoDB は、パーティションキーとソートキーしか検索条件に使えず、かつ、パーティションキーは完全一致の指定しかできない制約があるので、無計画にテーブルを作ると、いざアプリケーションを書いてみたら検索したかった条件で検索ができないとういことになりかねません。

スキーマレスとは言いつつも、最初から考えないといけないことがいろいろあって、想像と違ってた部分があって面食らいました。

アクセスパターン

数が少ないですが、ミニマムで以下のようなアクセスパターンを考えました。

ID アクセスパターン ソート
1 参加者としてすべてのイベントを取得する 開催日
2 参加者として自分が参加申し込みしたイベント一覧を取得する 申込日
3 参加者として特定の期間に開催されているイベント一覧を取得する 開催日
4 管理者として特定のイベントのイベント参加者一覧を取得する 申込日
5 管理者として特定の参加者が参加申し込みしているイベント一覧を取得する 申込日
6 管理者として締切間近のイベント一覧を取得する 申込締切日

最初の案

テーブル

テーブル1つ縛りな時点で、主キーは、パーティションキーを効率的に設計し、使用するためのベストプラクティス の冒頭の文章で言うところの「複合 (パーティションキーとソートキーの組み合わせ) で構成」することになりそうです。

SKに event-master と記載したアイテムはいわゆるマスターテーブルのデータを表したアイテムとして扱い、SK に user-{{userId}} と記載したアイテムはいわゆるトランザクションテーブルのデータを表したアイテムとして扱うことにしました。

この最初の案を考える際に多対多の関係を管理するためのベストプラクティスを参考にしました。

具体的には「隣接関係のリスト設計パターン」を使っています。

最初の案のテーブルの内容は下記です。

PK SK タイトル 内容 開催日 申込締切日 申込日
event-1 event-master イベント1のタイトル イベント1の内容 2020-12-01 2020-11-24
event-1 user-1 2020-11-01
event-1 user-2 2020-11-01
event-2 event-master イベント2のタイトル イベント2の内容 2020-12-24 2020-12-10
event-2 user-1 2020-11-01
event-2 user-2 2020-11-05
event-2 user-3 2020-11-02
event-2 user-4 2020-11-03

インデックス

なし

クエリ

アクセスパターン (ID=4) は、PK に対象のイベントID, SK に begins_with(user-) を指定すれば一見いけそうなのですが、今のままだと申込日によるソートや絞り込みはできません。

そこで、LSI(ローカルセカンダリインデックス)を作成することにします。

ID アクセスパターン ソート クエリ
1 参加者としてすべてのイベントを取得する 開催日
2 参加者として自分が参加申し込みしたイベント一覧を取得する 申込日
3 参加者として特定の期間に開催されているイベント一覧を取得する 開催日
4 管理者として特定のイベントのイベント参加者一覧を取得する 申込日
5 管理者として特定の参加者が参加申し込みしているイベント一覧を取得する 申込日
6 管理者として締切間近のイベント一覧を取得する 申込締切日

カイゼン1

アクセスパターン (ID=4) のための LSI を作成します。

テーブル

変更なし

インデックス

インデックス PK SK
LSI-1 PK 申込日

クエリ

LSI を追加するとアクセスパターン (ID=4) が実現できましたが、まだまだ実現したいアクセスパターンはあります。今回の要件には GSI(グローバルセカンダリインデックス)が必要不可欠です。(隣接関係のリスト設計パターンは GSI ありき)

ID アクセスパターン ソート クエリ
1 参加者としてすべてのイベントを取得する 開催日
2 参加者として自分が参加申し込みしたイベント一覧を取得する 申込日
3 参加者として特定の期間に開催されているイベント一覧を取得する 開催日
4 管理者として特定のイベントのイベント参加者一覧を取得する 申込日 LSI-1 を使って、PK=特定のイベントID, SK=全期間 を指定する
5 管理者として特定の参加者が参加申し込みしているイベント一覧を取得する 申込日
6 管理者として締切間近のイベント一覧を取得する 申込締切日

カイゼン2

SK を PK にした GSI をいくつか作るといろんなクエリが書けます。

テーブル

変更なし

インデックス

GSI-1 ~ GSI-3 を追加します。

インデックス PK SK
LSI-1 PK 申込日
GSI-1 SK 開催日
GSI-2 SK 申込日
GSI-3 SK 申込締切日

クエリ

一応これで、当初考えていたアクセスパターンが全部実現できそうです。

ID アクセスパターン ソート クエリ
1 参加者としてすべてのイベントを取得する 開催日 GSI-1 を使って、PK=event-master, SK=全期間 を指定する
2 参加者として自分が参加申し込みしたイベント一覧を取得する 申込日 GSI-2 を使って、PK=自身のユーザーID, SK=全期間 を指定する
3 参加者として特定の期間に開催されているイベント一覧を取得する 開催日 GSI-1 を使って、PK=event-master, SK=特定期間 を指定する
4 管理者として特定のイベントのイベント参加者一覧を取得する 申込日 LSI-1 を使って、PK=特定のイベントID, SK=全期間 を指定する
5 管理者として特定の参加者が参加申し込みしているイベント一覧を取得する 申込日 2. の PK が特定のユーザーIDに変わるだけ
6 管理者として締切間近のイベント一覧を取得する 申込締切日 GSI-3 を使って、PK=event-master, SK=締切日1週間前など を指定する

カイゼン3

GSI をたくさん作っちゃったので財布が不安です。

属性の使い方を工夫すればもう少し GSI を削減できそうなので、ちょっとやってみます。

具体的にはアイテム毎にソートに使用するデフォルトの日付を定めるイメージです。
イベントの情報を管理するアイテム(SKが event-master であるアイテム)であれば開催日、イベントの申込状況を管理するアイテム(SKが user-{{userId}} であるアイテム)であれば申込日とします。

ただ、ここのカイゼン案を適用すると、データの持ち方が冗長になるし、わかりにくくなるので、人によっては改悪と思う改修かもしれません。

テーブル

PK SK ソート日付 タイトル 内容 開催日 申込締切日 申込日
event-1 event-master 2020-12-01 (開催日と同じ値) イベント1のタイトル イベント1の内容 2020-12-01 2020-11-24
event-1 user-1 2020-11-01 (申込日と同じ値) 2020-11-01
event-1 user-2 2020-11-01 (申込日と同じ値) 2020-11-01
event-2 event-master 2020-12-24 (開催日と同じ値) イベント2のタイトル イベント2の内容 2020-12-24 2020-12-10
event-2 user-1 2020-11-01 (申込日と同じ値) 2020-11-01
event-2 user-2 2020-11-05 (申込日と同じ値) 2020-11-05
event-2 user-3 2020-11-02 (申込日と同じ値) 2020-11-02
event-2 user-4 2020-11-03 (申込日と同じ値) 2020-11-03

インデックス

GSI-1 と GSI-2 を GSI-4 として統合できました。

ちなみに LS1-1 の SK は申込日をそのまま使う必要があります。申込日はイベントの申込状況を管理するアイテム(SKが user-{{userId}} であるアイテム)にしか含まれていない属性なので、SK を申込日にすれば、申込日が属性として存在するアイテムだけを検索対象とできます。この場合、申込日が Take Advantage of Sparse Indexes で言うところの Sparse インデックスに相当することになります(多分)。

インデックス PK SK
LSI-1 PK 申込日
GSI-4 SK ソート日付
GSI-3 SK 申込締切日

クエリ

ID アクセスパターン ソート クエリ
1 参加者としてすべてのイベントを取得する 開催日 GSI-4 を使って、PK=event-master, SK=全期間 を指定する
2 参加者として自分が参加申し込みしたイベント一覧を取得する 申込日 GSI-4 を使って、PK=自身のユーザーID, SK=全期間 を指定する
3 参加者として特定の期間に開催されているイベント一覧を取得する 開催日 GSI-4 を使って、PK=event-master, SK=特定期間 を指定する
4 管理者として特定のイベントのイベント参加者一覧を取得する 申込日 LSI-1 を使って、PK=特定のイベントID, SK=全期間 を指定する
5 管理者として特定の参加者が参加申し込みしているイベント一覧を取得する 申込日 2. の PK が特定のユーザーIDに変わるだけ
6 管理者として締切間近のイベント一覧を取得する 申込締切日 GSI-3 を使って、PK=event-master, SK=締切日1週間前など を指定する

カイゼンn

ドキュメントを読み込むと、まだ適用できそうなベストプラクティスがいくつかあります。

  1. SK(GSI-3, 4 の PK)の event-master のホットパーティション化問題
  2. クエリ条件(GSI)がもっと増えていく問題

とは言え、この辺を適用してしまうとアプリケーション側の実装がやたらめったら複雑になってしまいそうなので、今回のお試しテーブル設計ではこの辺までにしておこうかなと思います。

まとめ

RDB よりも考えることが多そうで難しいと思いました。上記が正解なのかも正直よくわかりません。

DynamoDB の特性ありきのハイコンテキストなスキーマなので、こういう風にできたスキーマを理解して、正しく使って、維持するのは大変そうだなという印象です。

ただ、縛りプレイのお試しテーブル設計をしたことで少しだけ DynamoDB についての理解が深まった気はしました。

以上。


  1. Amplify は LSI を設定したり、REST API モデルだと GSI を後から追加したりができないっぽく(属性を定義するタイミングでならできる)て辛い感じでした。 

  2. いろんな記事で公式ドキュメントの文言として上記の文言が引用されているものの、最新版の公式ドキュメントからは削られていました。今は事情が違う? 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker compose build のメモリ容量不足の対策

こちら参照。
https://kazmax.zpp.jp/linux_beginner/mkswap.html

解決策 swap領域を追加し、bundle installを可能にする。

以下エラー文。

Installing nokogiri 1.10.10 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /usr/local/bundle/gems/nokogiri-1.10.10/ext/nokogiri
/usr/local/bin/ruby -r ./siteconf20201104-6-1o7c1oy.rb extconf.rb
Cannot allocate memory - /usr/local/bin/ruby -r ./siteconf20201104-6-1o7c1oy.rb
extconf.rb 2>&1

Gem files will remain installed in /usr/local/bundle/gems/nokogiri-1.10.10 for
inspection.
Results logged to
/usr/local/bundle/extensions/x86_64-linux/2.5.0/nokogiri-1.10.10/gem_make.out

An error occurred while installing nokogiri (1.10.10), and Bundler cannot

continue.
Make sure that `gem install nokogiri -v '1.10.10' --source
'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  rails was resolved to 5.2.4.4, which depends on
    actioncable was resolved to 5.2.4.4, which depends on
      actionpack was resolved to 5.2.4.4, which depends on
        actionview was resolved to 5.2.4.4, which depends on
          rails-dom-testing was resolved to 2.0.3, which depends on
            nokogiri
ERROR: Service 'app' failed to build: The command '/bin/sh -c bundle install' returned a non-zero code: 5
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSで80ポートを開いてるのに【このサイトにアクセスできません】が出る

image-2.png

先日Railsアプリをsslで通信したいと考えRailsでconfig.force_sslを設定してからなぜかアプリが表示されなくなったため、その時の対処法をまとめました。

アプリの状態

アプリ名 my-app
server EC2
web server nginx
application server unicorn
解放ポート 80, 443, 22

まずはセキュリティグループを確認

いつものことかと思い

AWS→セキュリティグループ→対象のパブリックなセキュリティグループを確認

しかし特に異常は見つからず80番と443番はしっかり開いてました。
普通なら通信はできるはずなのですが…

ちなみにlocal環境からEC2インスタンスへssh通信はできているようです。

nginxが80ポートにlistenしているかを確認

続いてnginxの設定ファイルを確認し80ポートにlistenされているか。

$ssh USER@MY-ELASTIC-IP

$ cat /etc/nginx/conf.d/my-app.conf


upstream unicorn {
          server unix:/var/www/my-app/shared/tmp/sockets/unicorn.sock;
}
server {
  listen 80; <-----------
  server_name ELASTIC-IP;
  root /var/www/my-app/current/public;

  access_log /var/log/nginx/nginx_access.log;
  error_log  /var/log/nginx/nginx_error.log;


  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}

ポート指定も問題ないようです。

コンソールからポートが開いているかチェック

$ netstat -tln

# 接続しているものでlisten済みのものを表示

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::3306                 :::*                    LISTEN
tcp6       0      0 :::111                  :::*                    LISTEN

確認してみると確かに接続を許していないようです。なぜ22ポートだけが開いているのかわかりません。

試しにこの状態でセキュリティグループをいじくっても結果は変わらず…

セキュリティグループの他にもネットワークインターフェースやネットワークACL、インターネットゲートウェイ、ルートテーブルなども確認してみたのですが結果は変わりませんでした、

結論 ngixnの不調でした

結局nginxを調べてみることに。
すると…

$ sudo nginx -s reload

----------------------------------------------------------------------

nginx: [error] open() "/var/run/nginx.pid" failed (2: No such file or directory)

capistranoでデプロイした際は特に問題なくunicornは起動していたので見落としてしまっていましたがここに原因があったようです。

nginxpidファイルが消失してしまっていたため作り直します。

ngixn 再起動

$ sudo service nginx stop

$ sudo touch /run/nginx.pid     

$ nginx -t

$ sudo service ngixn start  

再び確認

$ sudo service ngix status

----------------------------------------------------------------------
Redirecting to /bin/systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2020-10-30 06:05:36 UTC; 3h 28min ago
  Process: 22103 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 22100 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 22099 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 22106 (nginx)
   CGroup: /system.slice/nginx.service
           ├─22106 nginx: master process /usr/sbin/nginx
           └─22111 nginx: worker process

Oct 30 06:05:36 ip-10-0-0-178.us-east-2.compute.internal systemd[1]: Starting The nginx HTTP and reverse proxy server...
Oct 30 06:05:36 *p-10-0-0-178.us-east-2.compute.internal nginx[22100]: nginx: the configuration file /etc/nginx/ngi...ok
Oct 30 06:05:36 ip-10-0-0-178.us-east-2.compute.internal nginx[22100]: nginx: configuration file /etc/nginx/nginx.c...ul
Oct 30 06:05:36 ip-10-0-0-178.us-east-2.compute.internal systemd[1]: Failed to read PID from file /run/nginx.pid: ...ent
Oct 30 06:05:36 ip-10-0-0-178.us-east-2.compute.internal systemd[1]: Started The nginx HTTP and reverse proxy server.
Hint: Some lines were ellipsized, use -l to show in full.

その後

$ netstat -tlnt

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::3306                 :::*                    LISTEN
tcp6       0      0 :::111                  :::*                    LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN

解決しました!

nginxが上手く機能していないとすると80ポートが閉じてしまうのは知らなかったですね…

原因はおそらくインスタンスの再起動

rails で config.force_ssl = trueを使用

sslに必要な設定を行っていなかったため表示エラー

その際EC2インスタンスを再起動したため上手くnginxが機能していなかったのだと思います。

config.force_sslエラーについてはこちらの記事にまとめました。
>>【config.force_ssl】を使用したらページが表示されなくなった

次回同じようなエラーに遭遇したらまずはnginxからポートが開いているかを確認してからawsコンソールを弄ろうと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

備忘録:AWSのElastic Beanstalk でnginxの設定拡張 (client_max_body_size )

環境

  • Spring Boot + React
  • Elastic BeanStalk
    • Corretto 11
    • Amazon Linux 2

バグ

練習のため、Spring Boot + ReactのCRUDアプリをAWSのElastic BeanStalkにデプロイしたところ、ファイル容量の大きい画像投稿ができない。

spring.servlet.multipart.max-file-size=10MBの設定をSpring Boot側ではしており、ローカルでは投稿できるサイズの画像を投稿できず、413 Request Entity Too Largeエラーが出ている。

nginxのエラーログ(var/log/nginx/error.log)

2020/11/03 10:42:27 [error] 31794#0: *108 client intended to send too large body: 3275907 bytes,...

エラー内容をググると、nginxはデフォルトで、リクエストボディのサイズに1MBまでという上限が設定されていることが分かった。この上限を変えるには、client_max_body_sizeを変更しなければいけないらしい。

ソース
https://stackoverflow.com/questions/44741514/nginx-error-client-intended-to-send-too-large-body

Elastic Beanstalkでのnginx設定拡張方法

どうやらソースバンドルのルートに、以下のディレクトリ構造で.confファイルを作成し、client_max_body_size 10M;を記述すれば、ディプロイ時に設定を追加してくれるらしい。

├── .platform
│   └── nginx
│       └── conf.d
│           └── myconf.conf
└── myApp-0.0.1-SNAPSHOT.jar

ソース

  1. https://stackoverflow.com/questions/18908426/increasing-client-max-body-size-in-nginx-conf-on-aws-elastic-beanstalk
  2. https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

注:上の記事では、 .ebextensions/nginx/conf.d/以下となっているが、Amazon Linux2の場合、上記の.platform/nginx/conf.d/に追加するのが正しいようです(https://stackoverflow.com/questions/63430968/application-source-bundle-doesnt-work-when-uploaded-to-aws-elastic-beanstalk )。

試してみた

フォルダーを作成し、その中にjarとconfファイルを含んだ.platformフォルダをzip化→アップロードするも、deployエラーが出る。。。下記、eb-engine.logのエラー。confファイルの書き方を変えてみたり色々したけど、デプロイできない。。

[ERROR] An error occurred during execution of command [app-deploy] - [CheckProcfileForJavaApplication]. 
Stop running the command. Error: there is no Procfile and no .jar file at root level of your source bundle 

原因

結果、下記の記事によって、アーカイブのフォルダ構成が正しくないことが分かった。
対象ファイル/フォルダ自体を圧縮せずに、新たなフォルダに入れて圧縮していたのが原因だった...

解凍されたファイルが、新しい上位フォルダまたはディレクトリではなく、アーカイブ自体があるフォルダに表示されていることを確認します。

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/applications-sourcebundle.html

さらに試してみた

今度は無事、デプロイ成功!早速、画像投稿するも...

[error] 31794#0: *108 client intended to send too large body: 3275907 bytes,...

設定が変更されていない!!

原因

コマンドラインでzipコマンドを使うときに、-rオプションをつけていなかったため、./platform以下の中身が空っぽになっていた。。。

zip -r 圧縮後のファイル名.zip 圧縮したいファイル/フォルダ

上記が解決してやっと、設定が反映されました。

まとめ

  1. 同様環境下で、client intended to send too large body (413 Request Entity Too Large)エラーが出たら、nginxのclient_max_body_sizeを変更する。
  2. Elastic Beanstalkだと、簡単な方法として、ソースバンドルに設定ファイルを含むことで変更可能。
  3. ソースバンドルは、親フォルダまたは最上位ディレクトリを含まない(サブディレクトリを除く)。
  4. zip コマンドを使う場合、フォルダを含むなら、-rを忘れない。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

備忘録:AWSのElastic Beanstalk でnginxの設定拡張 client_max_body_size

環境

  • Spring Boot + React
  • Elastic BeanStalk
    • Corretto 11
    • Amazon Linux 2

バグ

練習のため、Spring Boot + ReactのCRUDアプリをAWSのElastic BeanStalkにデプロイしたところ、ファイル容量の大きい画像投稿ができない。

spring.servlet.multipart.max-file-size=10MBの設定をSpring Boot側ではしており、ローカルでは投稿できるサイズの画像を投稿できず、413 Request Entity Too Largeエラーが出ている。

nginxのエラーログ(var/log/nginx/error.log)

2020/11/03 10:42:27 [error] 31794#0: *108 client intended to send too large body: 3275907 bytes,...

エラー内容をググると、nginxはデフォルトで、リクエストボディのサイズに1MBまでという上限が設定されていることが分かった。この上限を変えるには、client_max_body_sizeを変更しなければいけないらしい。

ソース
https://stackoverflow.com/questions/44741514/nginx-error-client-intended-to-send-too-large-body

Elastic Beanstalkでのnginx設定拡張方法

どうやらソースバンドルのルートに、以下のディレクトリ構造で.confファイルを作成し、client_max_body_size 10M;を記述すれば、ディプロイ時に設定を追加してくれるらしい。

├── .platform
│   └── nginx
│       └── conf.d
│           └── myconf.conf
└── myApp-0.0.1-SNAPSHOT.jar

ソース

  1. https://stackoverflow.com/questions/18908426/increasing-client-max-body-size-in-nginx-conf-on-aws-elastic-beanstalk
  2. https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

注:上の記事では、 .ebextensions/nginx/conf.d/以下となっているが、Amazon Linux2の場合、上記の.platform/nginx/conf.d/に追加するのが正しいようです(https://stackoverflow.com/questions/63430968/application-source-bundle-doesnt-work-when-uploaded-to-aws-elastic-beanstalk )。

試してみた

フォルダーを作成し、その中にjarとconfファイルを含んだ.platformフォルダをzip化→アップロードするも、deployエラーが出る。。。下記、eb-engine.logのエラー。confファイルの書き方を変えてみたり色々したけど、デプロイできない。。

[ERROR] An error occurred during execution of command [app-deploy] - [CheckProcfileForJavaApplication]. 
Stop running the command. Error: there is no Procfile and no .jar file at root level of your source bundle 

原因

結果、下記の記事によって、アーカイブのフォルダ構成が正しくないことが分かった。
対象ファイル/フォルダ自体を圧縮せずに、新たなフォルダに入れて圧縮していたのが原因だった...

解凍されたファイルが、新しい上位フォルダまたはディレクトリではなく、アーカイブ自体があるフォルダに表示されていることを確認します。

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/applications-sourcebundle.html

さらに試してみた

今度は無事、デプロイ成功!早速、画像投稿するも...

[error] 31794#0: *108 client intended to send too large body: 3275907 bytes,...

設定が変更されていない!!

原因

コマンドラインでzipコマンドを使うときに、-rオプションをつけていなかったため、./platform以下の中身が空っぽになっていた。。。

zip -r 圧縮後のファイル名.zip 圧縮したいファイル/フォルダ

上記が解決してやっと、設定が反映されました。

まとめ

  1. 同様環境下で、client intended to send too large body (413 Request Entity Too Large)エラーが出たら、nginxのclient_max_body_sizeを変更する。
  2. Elastic Beanstalkだと、簡単な方法として、ソースバンドルに設定ファイルを含むことで変更可能。
  3. ソースバンドルは、親フォルダまたは最上位ディレクトリを含まない(サブディレクトリを除く)。
  4. zip コマンドを使う場合、フォルダを含むなら、-rを忘れない。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2/Docker/LaravelでHelloWorld

経緯

Laradocを使ったWebアプリの開発の勉強を始めています.

AWSとLaravel,docker,docker-compose勉強し始めて、1ヶ月ほどたって、
Docker/Doker Compose/AWSの使い方にはなれてきたので、Laradocでデプロイしてみたいなぁと思って、自分の勉強のために残しておきます。(2020年11月4日時点)

参考にさせていただいたのサイトは下記のところです。

https://laraweb.net/tutorial/6578/
https://noumenon-th.net/programming/2019/06/16/laradock/

参考にした本は「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版」です。

docker,docker-composeの基礎知識は下記のudemy講座で勉強しました。

https://www.udemy.com/course/aidocker/

色々な知識与えてくれた上記の作者の方々に感謝です。

では早速やっていきましょう

ゴール

AWSでどこからでもアクセスできるLaravelのWebアプリをデプロイする。
本来はローカルでLaradoc作って、Webアプリ開発してそれをgit cloneするのだと思いますが、
全部AWSで完結します。

laravelの実行環境

Ubuntu:18.04
PHP : 7.3
mysql : 5.4
Docker : 19.03.13
Docker-compose : 1.17.1

リージョンの選定

東京リージョンで作成しましょう

VPCの作成

image.png

image.png

1個のパブリックサブネットを持つVPCを作成します。
プライベートなサブネットを作りたいときは下のパブリックとプライベートサブネットを持つVPCを作ります。
このとき、IPv4 CIDRブロックは10.0.0.0/16
パブリックサブネットのIpv4 10.0.0.0/24にしておきましょう。
image.png

VPC
image.png

EC2インスタンスの作成

EC2をコンソールから選択してインスタンスを起動をクリック
image.png

Ubuntu 18.04を選択
ステップ2でt2.microを選択
image.png

ステップ3 インスタンスの詳細の設定では先程作成したVPCを選択.自動割当パブリックIPも無効から有効にしましょう。
image.png

ステップ6 セキュリティグループ設定ではHTTPの80ポートを使用するので、ルールの追加で追加する。
image.png

ステップ7 で起動をクリック。
      SSH接続するための、キーペア(mykey.pem)はダウンロードしておきましょう。

image.png

この間で、mykey.pemの認証をしましょう。

ダウンロードフォルダに移動して下記のコマンド実行しましょう
そうしたら認証が変わります。
chmod 400 mykey.pem
詳しくはawsの認証ページに書いてあります。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html

しばらくしたらインスタンスがrunnningになるので、EC2ダッシュボード⇒実行中のインスタンスをクリック⇒作成したインスタンスIDをクリック
右上にある接続をクリック
image.png

SSH接続する場合は下にあるところ(コピーされたコマンドをクリック)したらいいです。

image.png

ターミナルを開いて
mykey.pemのあるディレクトリに移動(cd)

先程AWSでコピーした
ssh ~~~
をターミナルに貼り付け。Enter

そしたら先程作成したEC2に入れます。
その後、
yesと入力
ここまででEC2の起動は終わりです。

EC2の中で、Docker,Git,Docker-composeをインストール

ubuntu@ip-10-0-0-205:~$ sudo su
root@ip-10-0-0-205:/home/ubuntu# 

以下root内での作業

じゃんじゃん下のコマンド打っていきましょう
apt-getのアップデートして,gitをインストール
apt-get update
apt-get install git

dockerとdocker-composeをインストール

$ apt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-common

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

$ apt-key fingerprint 0EBFCD88

$ add-apt-repository \
                      "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
                      $(lsb_release -cs) \
                      stable"
$ apt-get install docker-ce docker-ce-cli containerd.io

$ apt install docker-compose
exit

でrootから抜け出す

Laradocをgit cloneする。

https://laradock.io/

git clone https://github.com/Laradock/laradock.git

lsでgit cloneされているか確認しましょう。
image.png

$ cd laradockとして
$ cp env-example .env
とりあえず、PHP=7.3
mysqlで実行することにしてみましょう。
実行。

docker-compose up -d apache2 mysql

してapace2 mysqlのdockerを起動。
10分ほどまちます。Youtubeでも見ながらゆっくりしましょう。

workspaceコンテナに入ります。

dockerのインストールが終了したら、下記コマンド実行して、
workspaceで作業しましょう。

docker-compose exec --user=laradock workspace bash

でworkspace内で、docker-compose 起動します。

そうすると、var/www$に移動します。
laradockフォルダがあるので、

$ cd laradoock
として、.envファイルを編集します。
$ cp env-example .env
しましょう

下記を.envに追加
vi .env実行して下記追加。

DB_HOST=mysql
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

LaravelでWebアプリの作成

今回はサンプル用のアプリ名をSampleProjectとします。

laradock@e00afef1d36e:/var/www$ composer create-project laravel/laravel SampleProject "5.5.*"

そしたらSampleProjectができます。

var/www --- laradock
         |_ SampleProject

という構成になります。

SampleProjectに入って.envを編集。

DB_CONNECTION=mysql 
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

としてDB_HOSTをmysqlにします。

そして,Laradock内の.envを下記の通り編集して、起動するlaravelアプリを選択。
ここを記述しないと認識されないんだと思います。

APP_CODE_PATH_HOST=../SampleProject

とりあえずの設定は終わりました。

laradocのファルダに移動して、docker-compose再起動して、変更を読み込み。

docker-compose up -d nginx mysql phpmyadmin

あと少しでラストです。

Laravelの初期画面表示

EC2のパブリックIpv4 DNSをコピーして、
ブラウザのURLバーに貼り付け。(URLはElastic IPで固定にしてもいいですが、今回はしません。)

image.png

いけますね。疑い深いんで、ローカルじゃなくグローバルになってるか確認するために、iphoneで動くか確認してもいけてます。

image.png

EC2再起動したときの注意事項

1)EC2再起動するたびにdocker-compose再起動しましょう。
EC2停止すると再起動するらしいとのことなので、
EC2起動のたびdocker-compose立ち上げないといけないので、
下記のコマンド実行します。

sudo su
cd laradock/
docker-compose up -d nginx mysql phpmyadmin

2)EC2停止したときは、Ipアドレス変わっているので、
 Elastic IPで固定化しましょう。

3) Laradockのファイル変更したら
docker-compose up -d mysql phpmyadmin
しましょう。
編集するファイルはもちろんSampleProject。

所感とこれから

EC2使って立ち上げるのに、すごい便利だなと思いましたし、デプロイできると嬉しいですね、
ただ、EC2再起動したあとのDocker-composeの立ち上げとか、
EC2立ち上げたときに、gitとかDocker/Docker-compose入れるの手間だなと思っちゃいました。

これからは発展的な内容としてEC2の冗長化とECS(Fargate),CI/CDも勉強しようとおもいます。

なにか、みなさまの参考になれば幸いです。

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2/Docker/Laravelでデプロイ

経緯

Laradocを使ったWebアプリの開発の勉強を始めています.

AWSとLaravel,docker,docker-compose勉強し始めて、1ヶ月ほどたって、
Docker/Doker Compose/AWSの使い方にはなれてきたので、Laradocでデプロイしてみたいなぁと思って、自分の勉強のために残しておきます。(2020年11月4日時点)

参考にさせていただいたのサイトは下記のところです。

https://laraweb.net/tutorial/6578/
https://noumenon-th.net/programming/2019/06/16/laradock/

参考にした本は「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版」です。

docker,docker-composeの基礎知識は下記のudemy講座で勉強しました。

https://www.udemy.com/course/aidocker/

色々な知識与えてくれた上記の作者の方々に感謝です。

では早速やっていきましょう

ゴール

AWSでどこからでもアクセスできるLaravelのWebアプリをデプロイする。
本来はローカルでLaradoc作って、Webアプリ開発してそれをgit cloneするのだと思いますが、
全部AWSで完結します。

laravelの実行環境

Ubuntu:18.04
PHP : 7.3
mysql : 5.4
Docker : 19.03.13
Docker-compose : 1.17.1

リージョンの選定

東京リージョンで作成しましょう

VPCの作成

image.png

image.png

1個のパブリックサブネットを持つVPCを作成します。
プライベートなサブネットを作りたいときは下のパブリックとプライベートサブネットを持つVPCを作ります。
このとき、IPv4 CIDRブロックは10.0.0.0/16
パブリックサブネットのIpv4 10.0.0.0/24にしておきましょう。
image.png

VPC
image.png

EC2インスタンスの作成

EC2をコンソールから選択してインスタンスを起動をクリック
image.png

Ubuntu 18.04を選択
ステップ2でt2.microを選択
image.png

ステップ3 インスタンスの詳細の設定では先程作成したVPCを選択.自動割当パブリックIPも無効から有効にしましょう。
image.png

ステップ6 セキュリティグループ設定ではHTTPの80ポートを使用するので、ルールの追加で追加する。
image.png

ステップ7 で起動をクリック。
      SSH接続するための、キーペア(mykey.pem)はダウンロードしておきましょう。

image.png

この間で、mykey.pemの認証をしましょう。

ダウンロードフォルダに移動して下記のコマンド実行しましょう
そうしたら認証が変わります。
chmod 400 mykey.pem
詳しくはawsの認証ページに書いてあります。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html

しばらくしたらインスタンスがrunnningになるので、EC2ダッシュボード⇒実行中のインスタンスをクリック⇒作成したインスタンスIDをクリック
右上にある接続をクリック
image.png

SSH接続する場合は下にあるところ(コピーされたコマンドをクリック)したらいいです。

image.png

ターミナルを開いて
mykey.pemのあるディレクトリに移動(cd)

先程AWSでコピーした
ssh ~~~
をターミナルに貼り付け。Enter

そしたら先程作成したEC2に入れます。
その後、
yesと入力
ここまででEC2の起動は終わりです。

EC2の中で、Docker,Git,Docker-composeをインストール

ubuntu@ip-10-0-0-205:~$ sudo su
root@ip-10-0-0-205:/home/ubuntu# 

以下root内での作業

じゃんじゃん下のコマンド打っていきましょう
apt-getのアップデートして,gitをインストール
apt-get update
apt-get install git

dockerとdocker-composeをインストール

$ apt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-common

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

$ apt-key fingerprint 0EBFCD88

$ add-apt-repository \
                      "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
                      $(lsb_release -cs) \
                      stable"
$ apt-get install docker-ce docker-ce-cli containerd.io

$ apt install docker-compose
exit

でrootから抜け出す

Laradocをgit cloneする。

https://laradock.io/

git clone https://github.com/Laradock/laradock.git

lsでgit cloneされているか確認しましょう。
image.png

$ cd laradockとして
$ cp env-example .env
とりあえず、PHP=7.3
mysqlで実行することにしてみましょう。
実行。

docker-compose up -d nginx mysql

してnginx mysqlのdockerを起動。
10分ほどまちます。Youtubeでも見ながらゆっくりしましょう。

workspaceコンテナに入ります。

dockerのインストールが終了したら、下記コマンド実行して、
workspaceで作業しましょう。

docker-compose exec --user=laradock workspace bash

でworkspace内で、docker-compose 起動します。

そうすると、var/www$に移動します。
laradockフォルダがあるので、

$ cd laradoock
として、.envファイルを編集します。
$ cp env-example .env
しましょう

下記を.envに追加
vi .env実行して下記追加。

DB_HOST=mysql
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

LaravelでWebアプリの作成

今回はサンプル用のアプリ名をSampleProjectとします。

laradock@e00afef1d36e:/var/www$ composer create-project laravel/laravel SampleProject "5.5.*"

そしたらSampleProjectができます。

var/www --- laradock
         |_ SampleProject

という構成になります。

SampleProjectに入って.envを編集。

DB_CONNECTION=mysql 
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret

としてDB_HOSTをmysqlにします。

そして,Laradock内の.envを下記の通り編集して、起動するlaravelアプリを選択。
ここを記述しないと認識されないんだと思います。

APP_CODE_PATH_HOST=../SampleProject

とりあえずの設定は終わりました。

laradocのファルダに移動して、docker-compose再起動して、変更を読み込み。

docker-compose up -d nginx mysql phpmyadmin

あと少しでラストです。

Laravelの初期画面表示

EC2のパブリックIpv4 DNSをコピーして、
ブラウザのURLバーに貼り付け。(URLはElastic IPで固定にしてもいいですが、今回はしません。)

image.png

いけますね。疑い深いんで、ローカルじゃなくグローバルになってるか確認するために、iphoneで動くか確認してもいけてます。

image.png

EC2再起動したときの注意事項

1)EC2再起動するたびにdocker-compose再起動しましょう。
EC2停止すると再起動するらしいとのことなので、
EC2起動のたびdocker-compose立ち上げないといけないので、
下記のコマンド実行します。

sudo su
cd laradock/
docker-compose up -d nginx mysql phpmyadmin

2)EC2停止したときは、Ipアドレス変わっているので、
 Elastic IPで固定化しましょう。

3) Laradockのファイル変更したら
docker-compose up -d mysql phpmyadmin
しましょう。
編集するファイルはもちろんSampleProject。

所感とこれから

EC2使って立ち上げるのに、すごい便利だなと思いましたし、デプロイできると嬉しいですね、
ただ、EC2再起動したあとのDocker-composeの立ち上げとか、
EC2立ち上げたときに、gitとかDocker/Docker-compose入れるの手間だなと思っちゃいました。

これからは発展的な内容としてEC2の冗長化とECS(Fargate),CI/CDも勉強しようとおもいます。

なにか、みなさまの参考になれば幸いです。

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Linux2にAmazon Linux Extrasで7系のPHPをインストールする

Amazon Linux2でPHP7系がインストールできないんだけど!!??

この記事を書く30分前まで半ギレでコンソールと戦ってました。

故あってremi版のPHP7.1をインストールしようとしたところ、何回叩いても

error
Error: Package: php-xml-7.1.33-10.el7.remi.x86_64 (remi-php71)
           Requires: libxslt.so.1(LIBXML2_1.0.22)(64bit)
Error: Package: php-xml-7.1.33-10.el7.remi.x86_64 (remi-php71)
           Requires: libxslt.so.1(LIBXML2_1.0.18)(64bit)

っていう感じのが出てきて、一向にインストールが進まず、
この関連パッケージが足りないからインストールが出来ないんだろうと思って色々調べて試したけど、
「もう既に新しいの入ってて他のものに使われてるからインストールできないよ」
とかいうのが出てきて頭噴火。

救いの手

何回目かのインストール失敗後に、以下回答がAL2から帰ってきました。

php-fpm is available in Amazon Linux Extra topics "php7.2" and "lamp-mariadb10.2-php7.2" and "php7.3" and "php7.4"

To use, run
$ sudo amazon-linux-extras install :topic:

Learn more at
https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras

[要約]
その依存パッケで使うphp7.2とかなら、amazon-linux-extrasで使えるよ。
amazon-linux-extrasコマンドを叩いてごらん。
詳しくはドキュメントを見てね。

Amazon Linux Extrasってなに!?

CentOSにおける標準パッケージのようなものです。これはAmazon Linuxのサポートが切れる2023年6月30日まで長期サポートされます。

$amazon-linux-extras listで利用できるパッケージが一覧で見ることが出来ます。
php7.2~7.4まで使えるのは嬉しい!
当初入れようとしたのは7.1だったけど、7.2でも良かったので7.2を入れることにしました。

$ sudo amazon-linux-extras list
  0  ansible2                 available    \
        [ =2.4.2  =2.4.6  =2.8  =stable ]
  2  httpd_modules            available    [ =1.0  =stable ]
  3  memcached1.5             available    \
        [ =1.5.1  =1.5.16  =1.5.17 ]
  5  postgresql9.6            available    \
        [ =9.6.6  =9.6.8  =stable ]
  6  postgresql10             available    [ =10  =stable ]
  8  redis4.0                 available    \
        [ =4.0.5  =4.0.10  =stable ]
  9  R3.4                     available    [ =3.4.3  =stable ]
 10  rust1                    available    \
        [ =1.22.1  =1.26.0  =1.26.1  =1.27.2  =1.31.0  =1.38.0
          =stable ]
 11  vim                      available    [ =8.0  =stable ]
 15  php7.2                   available    \
        [ =7.2.0  =7.2.4  =7.2.5  =7.2.8  =7.2.11  =7.2.13  =7.2.14
          =7.2.16  =7.2.17  =7.2.19  =7.2.21  =7.2.22  =7.2.23
          =7.2.24  =7.2.26  =stable ]
 17  lamp-mariadb10.2-php7.2  available    \
        [ =10.2.10_7.2.0  =10.2.10_7.2.4  =10.2.10_7.2.5
          =10.2.10_7.2.8  =10.2.10_7.2.11  =10.2.10_7.2.13
          =10.2.10_7.2.14  =10.2.10_7.2.16  =10.2.10_7.2.17
          =10.2.10_7.2.19  =10.2.10_7.2.22  =10.2.10_7.2.23
          =10.2.10_7.2.24  =stable ]
 18  libreoffice              available    \
        [ =5.0.6.2_15  =5.3.6.1  =stable ]
 19  gimp                     available    [ =2.8.22 ]
 20  docker=latest            enabled      \
        [ =17.12.1  =18.03.1  =18.06.1  =18.09.9  =stable ]
 21  mate-desktop1.x          available    \
        [ =1.19.0  =1.20.0  =stable ]
 22  GraphicsMagick1.3        available    \
        [ =1.3.29  =1.3.32  =1.3.34  =stable ]
 23  tomcat8.5                available    \
        [ =8.5.31  =8.5.32  =8.5.38  =8.5.40  =8.5.42  =8.5.50
          =stable ]
 24  epel                     available    [ =7.11  =stable ]
 25  testing                  available    [ =1.0  =stable ]
 26  ecs                      available    [ =stable ]
 27  corretto8                available    \
        [ =1.8.0_192  =1.8.0_202  =1.8.0_212  =1.8.0_222  =1.8.0_232
          =1.8.0_242  =stable ]
 28  firecracker              available    [ =0.11  =stable ]
 29  golang1.11               available    \
        [ =1.11.3  =1.11.11  =1.11.13  =stable ]
 30  squid4                   available    [ =4  =stable ]
 31  php7.3                   available    \
        [ =7.3.2  =7.3.3  =7.3.4  =7.3.6  =7.3.8  =7.3.9  =7.3.10
          =7.3.11  =7.3.13  =stable ]
 32  lustre2.10               available    \
        [ =2.10.5  =2.10.8  =stable ]
 33  java-openjdk11           available    [ =11  =stable ]
 34  lynis                    available    [ =stable ]
 35  kernel-ng                available    [ =stable ]
 36  BCC                      available    [ =0.x  =stable ]
 37  mono                     available    [ =5.x  =stable ]
 38  nginx1                   available    [ =stable ]
 39  ruby2.6                  available    [ =2.6  =stable ]
 40  mock                     available    [ =stable ]
 41  postgresql11             available    [ =11  =stable ]
 42  php7.4                   available    [ =stable ]
 43  livepatch                available    [ =stable ]
 44  python3.8                available    [ =stable ]
 45  haproxy2                 available    [ =stable ]
 46  collectd                 available    [ =stable ]
 47  aws-nitro-enclaves-cli   available    [ =stable ]
 48  R4                       available    [ =stable ]

いざ実践

php7.2インストール
$ sudo amazon-linux-extras install php7.2
~
Installed:
  php-cli.x86_64 0:7.2.34-1.amzn2 php-fpm.x86_64 0:7.2.34-1.amzn2 php-json.x86_64 0:7.2.34-1.amzn2 php-mysqlnd.x86_64 0:7.2.34-1.amzn2
  php-pdo.x86_64 0:7.2.34-1.amzn2

Dependency Installed:
  libzip5.x86_64 0:1.7.3-1.el7.remi                                  php-common.x86_64 0:7.2.34-1.amzn2

Complete!
phpバージョンチェック
$ php -v
PHP 7.2.34 (cli) (built: Oct 21 2020 18:03:20) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

一瞬で終わったが?

感想

これを知ってれば、余計なリポジトリ入れたりインストールしたりしてインスタンスを汚さずにすみました。。
弊社は基本CentOSでご提供をするんですが、Amazon Linuxの方がミドルウェアの対応が広いなら、
こっちの方が良いかもしれませんね…。
OS標準外のPHPも特別対応で出したりしてますが、サポート2年とかで切れちゃいますし。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

https化(SSL化)するプロセスで出てきたわからない用語・知識

ポートフォリオをhttps化(SSL化)しました。
わからない用語がたくさん出てきたので、調べたことをまとめました。

http化とは?

・ざっくりいうと、https://〜で始まるIPアドレスでアクセスできるようにすること。
http://abc.work/ から https://abc.work/ にアクセスできるようにすること。

なぜhttp化するのか?

・httpよりhttpsで通信した方が安全な通信だから。
・httpsのsは「Secure(安全)」のs。

なぜhttpよりhttpsで通信した方が安全な通信なのか?

・httpでの通信は暗号化されていない通信方式(安全でない通信)。通信が丸見えのため、フォームに入力した内容などが抜き取られるなどのリスクがある。パスワードやクレジットカード情報などが流出する恐れがある。

・httpsでの通信は暗号化された通信方式(安全な通信)。通信が暗号化されている(見えない)ため、情報流出などのリスクが低い。

https化はどうやるのか?

やり方は1つではなく、いくつかのパターンがある。

  1. ELB(+ACM発行証明書)→EC2
  2. ELB(+証明書)→EC2(+外部SSL証明書)
  3. CloudFront(+証明書)→ELB→EC2
  4. NLB→EC2(+外部SSL証明書)  などなど。

ナレコムAWSレシピ AWSでWebサイトをHTTPS化 その1:ELB(+外部証明書)→EC2編

今回はもっとも簡単な 1. の方法でやりました。
手順は以下の通りです。

[1] Route 53にサブドメイン作成
[2] ACM証明書設定
[2.1] ACMに外部証明書をインポート
[3] EC2インスタンス作成
[4] ELB作成
[5] 動作確認

https化しようとしてる方はこちらの記事を参考にしてください。
ナレコムAWSレシピ AWSでWebサイトをHTTPS化 その1:ELB(+外部証明書)→EC2編

ロードバランサーとは?

・AWSのEC2インスタンスにある装置。

ロードバランサーとは、その名の通りサーバーにかかる負荷(load)を、平等に振り分けるための装置のこと。これによって1つのサーバーにかかる負担を軽減したり、停止状態を防ぐことができる。
・Webサイトへのアクセス集中やサーバー故障などの場合でも、アクセス中の利用者に安定したサービス提供が継続可能になる。

カゴヤのサーバー研究室 【図で理解】ロードバランサーとは?負荷分散の仕組みを解説

セキュリティグループとは?

・セキュリティグループは、同一グループ外のインスタンスと通信を行う際のトラフィックを制御するファイアウォール。
・EC2とVPCに存在し、動作や設定に違いがある。

トラフィックとは?
Webの分野では、WebサーバやWebサイトへの外部からの接続要求数、アクセス数、送信データ量などのことや、サイトやページの間を行き来する閲覧者の流れのことをトラフィックということが多い。

ファイアウォール(Firewall)とは?
・企業などの内部ネットワークをインターネットを通して侵入してくる不正なアクセスから守るための“防火壁”。
・WANの発展によりWeb経由で内部ネットワークに侵入できるようになり、内部データの盗聴、改ざん、攻撃のリスクが出てきた背景から誕生した。

WANとは?
「Wide Area Network」の略で、遠く離れた場所とつながったネットワークのことで、だれもが自由に接続できるネットワークのこと。 簡単に言えばLANとLANをつないだ大きなネットワーク。インターネットもWANのひとつ。WANを利用することで世界中の人とのコミュニケーションが可能になった。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Databricks E2リリースで新しく追加された機能について

はじめに

2020年9月、AWS上で利用可能なdatabricksのプランに新しく E2 が追加されました。
この記事では、E2の機能について紹介していきます。

プランの概要

E2のプランにすることで、以下の機能が使えるようになります。

  • マルチワークスペースアカウント
  • 顧客管理VPC
  • 安全なクラスター接続
  • ノートブックの顧客管理キー

それぞれの機能について、見ていきます。

1. Multi-workspace accounts

アカウントAPIを使用し、単一のDatabricksアカウントで、複数の新しいDatabricksワークスペースをプログラムで作成することが可能です。作成する各ワークスペースには 異なる構成を設定できます。

2. Customer-managed VPCs

デフォルトでは、Databricksは各ワークスペースのAWSアカウントにVPCを作成しますが、E2の場合、この顧客管理VPC機能により独自のVPCにDatabricksワークスペースを作成することができます。

image.png

3. Secure cluster connectivity

すべてのノードがプライベートIPアドレスのみを持つクラスターを起動し、VPCに開いているポートがなくなることで、安全なクラスター接続が実現できます。

image.png

4. Customer-managed keys for notebooks

ワークスペースの作成中に、CMK(顧客管理キー)と呼ばれる取り消し可能な秘密鍵を追加することができます。CMKとDMK(データ暗号キー)を結合し、ワークスペースにDEK(派生暗号キー)を作成します。

image.png

価格について

11月4日現在では、公式ページでは価格オプションについて確認できませんでした。もしかすると現行のEnterpriseプランに含まれているかもしれませんので、今後確認でき次第追記していきます。

まとめ

これらの機能によって、より安全でスケーラブルに、AWS上でdatabricksプラットフォームを利用することができそうですね。

公式ドキュメント

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudWatchLogInsightでApacheのログを出力する

背景

Apache@EC2のアクセスログをAWSのログインサイトで調査する際の備忘録。
※ Kibanaにしたい。。。

Apache / httpd.conf / LogFormat

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" xforwarded

CloudWatchLogs / Logs Insights / Query

parse '* - * [*] "* * *" * * * "*" *' as host, identity, dateTimeString, httpVerb, url, protocol, statusCode, bytes,Referer,UserAgent,latency
| sort dateTimeString desc
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】OpsWorksでsetup_failedになったインスタンスにRun Commandさせる裏技

setup_failedで起こる問題

AWSのOpsWorksでは、正常に起動できたEC2インスタンスについては、
下記の画像のようにボタンをクリックすれば専用の画面に遷移し、
Run Commandが実行できる。
スクリーンショット 2020-11-04 13.22.28.png

しかし、起動が失敗(setup_failed)のインスタンスについては、
下記の画像のように画面遷移のボタンが表示されず、Run Commandが実行出来ない。
※ SSHとEditのボタンしか表示されない。

スクリーンショット 2020-11-04 13.21.44.png

解決の裏技

正常に起動できたインスタンス(今回でいえばaether)からRun Commandボタンをクリックし、専用画面に遷移する。
すると、Commandを選択する項目の他に、「実行するインスタンスを選択」する項目が下の方にある。
実はsetup_failedしたインスタンス(今回でいえばchaos)についても選択出来てしまうので、
chaosをチェックしaetherのチェックを外してあげれば、chaosにRun Command実行可能となる。

スクリーンショット 2020-11-04 13.23.34.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ec2の容量問題

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[aws] CodeCommit リポジトリ作成と動作確認

概要

CodeCommitによるソース管理を始めるための開始方法をスクショを入れてまとめます。
基本的に以下内容に沿った内容となっています。
https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/getting-started.html

リポジトリの作成

https://console.aws.amazon.com/codesuite/codecommit/home にアクセスし、リポジトリを作成を押下

スクリーンショット 2020-11-04 10.24.08.png

リポジトリ名を設定し、作成を押下。

スクリーンショット 2020-11-04 10.31.52.png

SSHによるリポジトリのクローン

SSHでのリポジトリクローンはIAMユーザでのみ実行可能です。
CodeCommitように公開鍵を予め登録しておく必要があります。

$ ssh-keygen
$ cat ~/.ssh/id_rsa.pub

上記で出力された公開鍵をIAMユーザに登録します。

スクリーンショット 2020-11-04 10.49.09.png

ローカルマシンの~/.ssh/configに接続情報を記載します。
Userの値は公開鍵を登録した際のSSHキーIDです。

~/.ssh/config
Host git-codecommit.*.amazonaws.com
  User APKAZ6CO7NSLEFREIC4T
  IdentityFile ~/.ssh/id_rsa

ローカルマシンでcloneを行います。
cloneのURLはCodeCommitで作成したリポジトリの画面から確認できます。

$ git clone ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/practice_ripo
Cloning into 'practice_ripo'...
warning: You appear to have cloned an empty repository.

gitの使い方は基本的に同じなため割愛します。

CloudFormationによるリポジトリの作成

リポジトリの作成を自動化するため、CloudFormationを使用し環境の作成を行います。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-codecommit-repository.html

リポジトリを作成するだけであれば以下が最小単位となります。

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  codecommit:
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: practice
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】ECS Serviceの監視をCFnで設定する

ECS ServiceのCPU使用率とタスク数をCloudWatch Alarm・SNS・ChatBotを利用して監視したいと思います。
リソース構築にはCloudFormation(以下CFnと略)を使います。

前提

  • 監視対象のECS Cluster・Serviceが既に構築済み
  • Container Insightsが有効になっている

要件

  • 共通
    • 正常(OK)・異常(ALARM)の通知
  • CPU使用率
    • 80%を超過したら通知
  • タスク数
    • 2個未満になったら通知

CFn

AWSTemplateFormatVersion: 2010-09-09

####################################################
# Parameters
####################################################

Parameters:
  # 監視対象のECS Cluster
  EcsClusterName:
    Type: String
  # 監視対象のECS Service
  EcsServiceName:
    Type: String

####################################################
# Resources
####################################################

Resources:
  SampleSNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        # 向き先をChatBotにする
        - Endpoint: https://global.sns-api.chatbot.amazonaws.com
          Protocol: HTTPS
      TopicName: sample

  CpuUtilizationAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      MetricName: CPUUtilization
      Namespace: AWS/ECS
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: 1
      Period: 60
      Statistic: Average
      Threshold: 80
      AlarmActions:
        - !Ref SampleSNSTopic
      AlarmDescription: CPU utilization is 80% or more
      Dimensions:
        - Name: ClusterName
          Value: !Ref EcsClusterName
        - Name: ServiceName
          Value: !Ref EcsServiceName
      OKActions:
        - !Ref SampleSNSTopic

  EcsTaskCountAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      MetricName: RunningTaskCount
      Namespace: ECS/ContainerInsights
      ComparisonOperator: LessThanThreshold
      EvaluationPeriods: 1
      Period: 60
      Statistic: Average
      Threshold: 2
      AlarmActions:
        - !Ref SampleSNSTopic
      AlarmDescription: Running task count is less than 2
      Dimensions:
        - Name: ClusterName
          Value: !Ref EcsClusterName
        - Name: ServiceName
          Value: !Ref EcsServiceName
      OKActions:
        - !Ref SampleSNSTopic

備考

上記のCFnは既存のChatBotを利用する想定なので、ChatBotのマネコンからSNSトピックの追加作業があります。
(ChatBotはCFnでも管理できます -> AWS::Chatbot::SlackChannelConfiguration - AWS CloudFormation)

Reference

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS〜VPCでネットワークを構築する①〜

この記事を読んでできるようになること

AWSでVPCを作成し、ネットワークを構築するための基礎を学ぶことができる。

記事を読むにあたってのお願い

私はAWSの初学者で、アウトプットをすることで知識を定着させるためにこの記事を書いています。内容に誤りがある場合は、コメントをいただけますと幸いです。
学習に使用した教材
AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得
https://www.udemy.com/course/aws-and-infra/

AWS・ネットワークの基礎知識

リージョンとは

AWSが提供されている地域のこと。
アジアだと東京やソウルなどがある。

アベイラビリティゾーンとは

各リージョンに存在するデータセンターのこと。
リージョンごとに複数のアベイラビリティゾーンが存在する。インスタンス(EC2で作成したサーバー)を複数のアベイラビリティゾーンに設置し、1つのインスタンスに障害が発生しても他のインスタンスで要求を処理するように設定することができる。(障害に強くなる)

VPCとは

Virtual Private Cloudの略で、AWSクラウド内にユーザーごとにプライベートなクラウド環境を提供するサービスのこと。
この中に、サーバーを設置し、Webサービスなどを提供する。

サブネットとは

VPCを管理しやすいように細かく分割したネットワークのこと。

IPアドレスとは

ネットワーク上に存在する機器を識別するためのインターネットにおける住所のこと。
32ビットの整数で表されるが、読み取りにくいので8ビット4つに分けて10進数で表現する。
00001111 00000111 00000011 00000001 → 読みにくい
15.7.3.1 といった形で表す。

パブリックIPアドレス

インターネット接続の際に用いるIPアドレスのこと。

プライベートIPアドレス

インターネットに接続する必要のない時に使用するIPアドレスのこと。
社内LANなど。

IPアドレスの範囲について

10.0.0.0~10.0.0.255というIPアドレスの範囲を指定したとする。
数字が変わらない最初の3つの数字部分 10.0.0 をネットワーク部といい、可変する最後の数字 0~255 をホスト部という。ネットワーク部で自分のネットワークまで通信がきて、ホスト部で自分のネットワーク内のどのデバイスに通信をするかを決定している。

CIDR(サイダー)表記について

ネットワーク部が最初の何ビットかを"IPアドレス/数字"で表す表記のこと。
10.0.0.0~10.0.0.255であれば 10.0.0 すなわち最初の24ビットがネットワーク部であるため、10.0.0.0/24と表記する。

サブネットマスク表記について

ネットワーク部のビットを"1"で表し、ホスト部のビットを"0"で表現した表記法。
こちらは、説明が難しいので表記を見てください。
①10.0.0.0~10.0.0.255をビット表記に変換
00001010.00000000.00000000.00000000~00001010.00000000.00000000.11111111
②ネットワーク部(最初の24ビット)を"1"に、ホスト部(最後の8ビット)を"0"に変換
11111111.11111111.11111111.00000000
③②の数字を10進数へ変換
255.255.255.0
④③の数字をCIDR表記でいう"24"のところに表記
10.0.0.0/255.255.255.0

AWSでは、CIDR表記でIPアドレスの範囲を表現する。

次は実際にVPCを作成し、ネットワークを構築していきたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【WIP】AWS学習

参考になった資料、書籍をまとめておく、備忘録

awsのハンズオン

Udemy で AWS を学んでみた(1)

AWS:ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得

Terraformについて

Terraformとは?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

独自ドメインを取得し、サイトをSSL化対応するまでを全てAWS上で行ってみた。

この度AWS SAA試験を受験することに決め、勉強の一環として
AWSで独自ドメインの取得からそれをサイトに割り当て、SSL化対応するまでを実際にやってみました。
以下備忘録として完了までの手順をまとめてみようと思います。

必要手順

・EC2インスタンスを取得
・インスタンスにElastic IPの割り当て
・Route53で独自ドメインの取得
・ACMでSSL証明書の取得
・ELBを設定
・DNSを設定

大まかな手順は以上なのですがこれらの手順の中身をざっと説明していきます。

EC2インスタンスを取得

まずは今回ドメインを付与する予定のwebサーバーをEC2にて作成します。

インスタンスにElastic IPの割り当て

EC2に割り当てられたパブリックIPは停止状態から起動する際にそのつど変更されてしまいます。
そのためElastic IPを割り当て、パブリックIPを固定します。

Route53で独自ドメインの取得

AWSのサービスの一つであるRoute53にはドメインを登録できる機能があるのでこちらで今回使う独自ドメインの登録を行います。
ドメインには種類があり、料金は種類に応じて変動します。
最低でも1年間からの年間契約であり、今回は1年間の契約で登録しました。

ACMでSSL証明書の取得

これもまたAWSのサービスであるACM(AWS Certificate Manager)でSSL証明書の発行ができます。
証明書のリクエスト画面から追加予定のドメイン名を入力し、進むとDNSまたEメールでの検証方法が提示されますのでどちらかを選択し、状況が発行済みとなれば使用できます。

ELBを設定

調べていく中で知ったのですがACMで発行した証明書をEC2に与えることはできないらしく、
そのためロードバランサーを設置しそちらに証明書を使用していきます。

DNSを設定

Route53にて作成したドメインのAレコードを選択し、ロードバランサーを設定します。

ブラウザにて確認

以上で作成したwebサイトへのSSL化対応が完了です。
各手順ごとの細かい作成内容は記載しなかったのですが公式のチュートリアルでインスタンスの作成からDNSの設定までまとめられていますので同じことをやってみる方は参考にしてみてください。
https://aws.amazon.com/jp/getting-started/hands-on/get-a-domain/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む