- 投稿日:2020-01-04T23:31:16+09:00
インフラエンジニアがwebアプリ作ってみる#1
1. 初めに
令和2年になりました。社会人2年目で仕事にもある程度慣れてきて、今年も頑張ろうと思っていた時ふと「あれ?俺ってアプリ開発全然できなくね?」と気付いてしまいました。
というのは私はインフラSEとして入社して以来一貫してインフラ基盤の初期構築ばかりやってきました。Ansible、Python、Javaとかは使っているものの、アプリ側のエンジニアとしてはとても飯を食っていけないレベルです。
更にインフラSEのくせにクラウド触ったことないです…。
市場価格なくなってしまうんでね?と思い新年やる気あるうちに自分でスキル高めようと決意した次第です。
三日坊主にならないように、Qiitaに投稿します。2. やりたいこと
とりあえずクオリティは置いといてwebアプリを作り切りたい!!!
ToDoアプリを作成し(Kotlin&Spring)期限ないに達成できないとLineBotから鬼責めされる三日坊主防止アプリを作りたいと思ってます。
(需要ないとか言わないで…)
フェーズ1としてローカルマシンにアプリを構築(キーワード:spring,Kotlin,Gradle,Postgres)
フェーズ2としてAWS上にアプリをデプロイ
フェーズ3としてCI/CD環境の整備
フェーズ4としてiOSアプリ化
をやってみたいです。3. 今後について
作成していく過程で使う技術を自分なりの言葉でまとめて記事投稿していきたいと思います。
4. お願い
間違ったこと、ナンセンスなことやってたら優しく指摘していただけると幸いです。
- 投稿日:2020-01-04T23:15:26+09:00
Cloud9にリモートデスクトップする方法
はじめに
AWSのCloud9は、AWSマネジメントコンソールからIDEとターミナルで開発や検証を進めますが、時々、ローカルのデスクトップ環境が欲しくなることがあります。
例えば、Webサイトやアプリケーションを開発すれば、ローカルのApache等に配置し、ブラウザから動作確認したいところです。
Pythonでrunserverを実行して、簡易的にWebサーバを起動して同様に動作確認したい場面もあるかと思います。
また、Cloud9にはdockerがプリインストールされているため、コンテナをbuildしたりupしたりすれば、ローカルで接続テストをしたい場面があるでしょう。
このような場面で、解説書やブログを参考にしていると、ブラウザで http://127.0.0.1:8000 や http://localhost 等に接続してGUIを確認する手順 (以下画像のようなこと) を指示される場合がありますが、Cloud9で開発していると手順通りに行かないため、先に進まなくなります。もしCloud9にローカルのデスクトップ環境があれば、Cloud9でローカル上にテスト環境を作った後、ブラウザを開いて、さくっと接続確認できるので、生産性が上がります。
そこで、Cloud9にデスクトップ環境をインストールし、リモートデスクトップする手順を調査し、整理してみました。
前提環境
- Cloud9: EC2環境 (OS: Ubuntu Server 18.04 LTS)
- インスタンスタイプ: t3.micro以上を推奨
- インストールするデスクトップ環境: MATE
※ 最後の接続確認はMacから実施しています。
構成図
Cloud9 (AWS) で実施する手順
1. Cloud9を構築する
環境の名前や説明はお好みで付ければOKです。
以下の画像の通り、Environment typeをEC2、PlatformをUbuntu Server 18.04 LTSとして構築します。
Point: 何故Amazon Linuxにしないのか
ここでAmazon Linuxを選んでも良いのですが、2020年1月の時点では、以下の理由で推奨しません。
- ここでAmazon Linuxを選択しても、Amazon Linux 2にはなりませんので、公式チュートリアルの手順でデスクトップ環境を作ることができません。
- Amazon Linux 2でCloud9を構築するにはSSH環境にする必要がありますが、SSH環境では一定時間操作がない時の自動停止機能が使えないので、私のようなズボラな方にはお勧めできません。
- Amazon Linuxは、2020年6月にサポートが終了します。
Q: Amazon Linux AMI はどれくらいの期間、サポートされますか?
AWS では 2020 年 6 月 30 日まで、Amazon Linux AMI 2018.03 の最新バージョンに対するセキュリティ更新の提供を継続し、Amazon Linux 2 への移行を促進します。Amazon Linux 2 では、2023 年 6 月 30 日まで長期サポートを受けることができます。2. デフォルトで作成されたEBSを拡張する
早速Cloud9に接続してデスクトップ環境をインストールしたいところですが、何もしないままにこの後紹介する手順でインストールを進めると、デフォルトで作成されるEBSボリュームの容量 (10GB) では不足してしまい、インストールが失敗します。
そこで、EBSボリュームを 10GB → 15GB に拡張します。
まずはAWSのマネジメントコンソールで、ボリュームの変更を行い、容量を拡張します。次に、拡張したEBSの容量を、OS上でも認識させます。
Cloud9のマネジメントコンソールを開き、ターミナルのウインドウで操作します。まず
lsblk
でパーティションを確認すると、拡張すべきパーティションが/dev/nvme0n1の1番目(MOUNTPOINTが/)だと分かりますので、sudo growpart /dev/nvme0n1 1
を実行して拡張します。
上記の実行後、パーティションを拡張した結果をlsblk
で確認すると、15GBになっていることが分かります。
次にdf -h
でファイルシステムを確認し、拡張すべきファイルシステムが/dev/nvme0n1p1だと分かりますので、sudo resize2fs /dev/nvme0n1p1
を実行して拡張します。
上記の実行後、ファイルシステムを拡張した結果をdf -h
で確認すると、15GBになっていることが分かります。コマンドは以下の通りとなります。
bashubuntu:~/environment $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 12.7M 1 loop /snap/amazon-ssm-agent/495 loop1 7:1 0 87.9M 1 loop /snap/core/5328 loop2 7:2 0 89.1M 1 loop /snap/core/8268 nvme0n1 259:0 0 15G 0 disk └─nvme0n1p1 259:1 0 10G 0 part / ubuntu:~/environment $ sudo growpart /dev/nvme0n1 1 CHANGED: partition=1 start=2048 old: size=20969439 end=20971487 new: size=31455199,end=31457247 ubuntu:~/environment $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 12.7M 1 loop /snap/amazon-ssm-agent/495 loop1 7:1 0 87.9M 1 loop /snap/core/5328 loop2 7:2 0 89.1M 1 loop /snap/core/8268 loop3 7:3 0 18M 1 loop /snap/amazon-ssm-agent/1480 nvme0n1 259:0 0 15G 0 disk └─nvme0n1p1 259:1 0 15G 0 part / ubuntu:~/environment $ df -h Filesystem Size Used Avail Use% Mounted on udev 468M 0 468M 0% /dev tmpfs 96M 764K 96M 1% /run /dev/nvme0n1p1 9.7G 7.6G 2.1G 79% / tmpfs 479M 0 479M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/loop0 13M 13M 0 100% /snap/amazon-ssm-agent/495 /dev/loop1 88M 88M 0 100% /snap/core/5328 tmpfs 96M 0 96M 0% /run/user/1000 /dev/loop2 90M 90M 0 100% /snap/core/8268 /dev/loop3 18M 18M 0 100% /snap/amazon-ssm-agent/1480 ubuntu:~/environment $ sudo resize2fs /dev/nvme0n1p1 resize2fs 1.44.1 (24-Mar-2018) Filesystem at /dev/nvme0n1p1 is mounted on /; on-line resizing required old_desc_blocks = 2, new_desc_blocks = 2 The filesystem on /dev/nvme0n1p1 is now 3931899 (4k) blocks long. ubuntu:~/environment $ df -h Filesystem Size Used Avail Use% Mounted on udev 468M 0 468M 0% /dev tmpfs 96M 764K 96M 1% /run /dev/nvme0n1p1 15G 7.6G 7.0G 53% / tmpfs 479M 0 479M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/loop0 13M 13M 0 100% /snap/amazon-ssm-agent/495 /dev/loop1 88M 88M 0 100% /snap/core/5328 tmpfs 96M 0 96M 0% /run/user/1000 /dev/loop2 90M 90M 0 100% /snap/core/8268 /dev/loop3 18M 18M 0 100% /snap/amazon-ssm-agent/1480ここまでの手順で、EBSの容量を 10GB → 15GB に拡張できました。
3. デスクトップ環境 (MATE) をインストールする
以下のコマンドを実行するだけです。
bashubuntu:~/environment $ sudo apt install ubuntu-mate-desktop4. vnc4serverをインストールして設定する
Cloud9にリモートデスクトップするために、以下のコマンドで、vnc4serverをインストールします。
bashubuntu:~/environment $ sudo apt install vnc4serverインストールが完了したら、以下のコマンド
vncserver :1
を実行し、一度VNCサーバを起動します。
コマンドを実行すると、デスクトップ環境にログインするためのパスワードの設定を求められますので、入力して設定します。
このパスワードは6文字以上8文字以下となり、8文字以上入力した時は、8文字目までがパスワードとして設定されます。bashubuntu:~/environment $ vncserver :1 You will require a password to access your desktops. Password: Verify: Password too long - only the first 8 characters will be used xauth: file /home/ubuntu/.Xauthority does not exist New 'ip-172-31-43-50:1 (ubuntu)' desktop is ip-172-31-43-50:1 Creating default startup script /home/ubuntu/.vnc/xstartup Starting applications specified in /home/ubuntu/.vnc/xstartup Log file is /home/ubuntu/.vnc/ip-172-31-43-50:1.log起動が完了したら、すぐVNCサーバを停止します。
bashubuntu:~/environment $ vncserver -kill :1 Killing Xvnc4 process ID 1058次に、一度起動したことによって、VNCサーバの設定ファイル
/home/ubuntu/.vnc/xstartup
が生成されていますので、この設定ファイルをMATE用に編集します。bash$ vi /home/ubuntu/.vnc/xstartup
設定ファイルの中身を、以下の内容に編集して保存します。
/home/ubuntu/.vnc/xstartup#!/bin/sh # Uncomment the following two lines for normal desktop: # unset SESSION_MANAGER # exec /etc/X11/xinit/xinitrc unset DBUS_SESSION_BUS_ADDRESS export XMODIFIERS="@im=fcitx" fcitx [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources xsetroot -solid grey # vncconfig -iconic & # x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & # x-window-manager & mate-session &5. vnc4serverの自動起動を設定
Cloud9を起動した時に、vnc4serverも自動起動するようにします。
~/.bashrc
を開き、最下行に起動コマンドを追記します。bashubuntu:~/environment $ vi ~/.bashrc
以下のように、最下行に起動コマンドを追記して保存します。
オプションの-geometry
は解像度、-depth
はビットカラー (8: 256色、16: 最大65536色、24: 最大16777216色)を示しますので、リモートデスクトップするクライアントの環境に合わせて変えてください。~/.bashrc# .bashrc export PATH=$PATH:$HOME/.local/bin:$HOME/bin (中略) # Add RVM to PATH for scripting. Make sure this is the last PATH variable change. export PATH="$PATH:$HOME/.rvm/bin" # ここから追記 vncserver :1 -geometry 1280x800 -depth 24保存後、OSを再起動します。
bashubuntu:~/environment $ sudo shutdown -r nowCloud9のマネジメントコンソール上に 「Connecting...」と表示されますので、自然に消えるのを待った後、次の手順に進みます。
6. SSHポートフォワードするため、パスワード認証を有効にする
デスクトップ環境にはインターネット経由で接続することになりますので、SSHポートフォワードを利用して、暗号化されたセキュアな接続にします。
Cloud9をubuntuユーザで利用する場合が殆どだと思いますので、デスクトップ環境もubuntuユーザで接続できるようにします。まず、ubuntuユーザのパスワードを設定します。
bash$ sudo passwd ubuntu Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully次に、
/etc/ssh/sshd_config
ファイルを編集し、PasswordAuthenticationのパラメータをyesに更新して保存します。bashubuntu:~/environment $ sudo vi /etc/ssh/sshd_config/etc/ssh/sshd_config(中略) # To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes #PermitEmptyPasswords no (中略)保存後、SSHのサービスを再起動します。
bashubuntu:~/environment $ sudo service ssh restart7. Security Groupで22番ポートを開放
クライアントPCからSSHポートフォワードを利用してリモートデスクトップするために、Cloud9のEC2インスタンスにアタッチされているSecurity Groupで22番ポートを開放します。
必ずクライアント側のグローバルIPを指定して/32で開放します。
開放すべきIPアドレスが分からない場合は、プルダウンで「マイIP」を選ぶと自動的に入力されます。
ここまでがCloud9側 (AWS側) の設定です。
クライアントPC側の設定
1. ターミナルからSSHポートフォワードする
AWSマネジメントコンソールでCloud9のEC2インスタンスにアタッチされたパブリックIPアドレスを確認し、クライアントPC側のターミナルで以下のコマンドを実行します。
以下のコマンドを実行した後、localhostの8888番ポートに接続すると、SSH経由でxxx.xxx.xxx.xxx(Cloud9)の5901番ポートに接続されます。bash$ ssh -L 8888:localhost:5901 ubuntu@xxx.xxx.xxx.xxx2. リモートデスクトップする
Macでは、Finderで「サーバへ接続」を開き、以下の通り入力して接続します。
接続すると、以下のようにデスクトップが開きます。
ここまでの手順で、Cloud9にデスクトップ環境をインストールして、クライアントからリモートデスクトップ接続ができました。
Cloud9でWebサーバを起動し、リモートデスクトップで動作確認する
Cloud9のMATEデスクトップ環境上のブラウザ (Firefox) を利用して、localhostに接続して動作確認できるかどうか試してみます。
まず、Cloud9でhttpd (Apache) を起動して、/var/www/htmlにテストファイルを置きます。
その後、リモートデスクトップでCloud9に接続して、ブラウザを開いて接続します。
このように、ブラウザを必要とする動作確認も、Cloud9のEC2インスタンス内だけで完結しますので、Cloud9で開発や検証を進める際の不便が一つ解消します。
- 投稿日:2020-01-04T23:15:26+09:00
Cloud9にDesktop (GUI) 環境をインストールする方法
はじめに
AWSのCloud9は、AWSマネジメントコンソールからIDEとターミナルで開発や検証を進めますが、時々、ローカルのデスクトップ環境が欲しくなることがあります。
例えば、Webサイトやアプリケーションを開発すれば、ローカルのApache等に配置し、ブラウザから動作確認したいところです。
Pythonでrunserverを実行して、簡易的にWebサーバを起動して同様に動作確認したい場面もあるかと思います。
また、Cloud9にはdockerがプリインストールされているため、コンテナをbuildしたりupしたりすれば、ローカルで接続テストをしたい場面があるでしょう。
このような場面で、解説書やブログを参考にしていると、ブラウザで http://127.0.0.1:8000 や http://localhost 等に接続してGUIを確認する手順 (以下画像のようなこと) を指示される場合がありますが、Cloud9で開発していると手順通りに行かないため、先に進まなくなります。もしCloud9にローカルのデスクトップ環境があれば、Cloud9でローカル上にテスト環境を作った後、ブラウザを開いて、さくっと接続確認できるので、生産性が上がります。
そこで、Cloud9のEC2インスタンスを構築し、デスクトップ環境をインストールし、リモートデスクトップする手順を調査し、整理してみました。
前提環境
- Cloud9: EC2環境 (OS: Ubuntu Server 18.04 LTS)
- インスタンスタイプ: t3.micro以上を推奨
- インストールするデスクトップ環境: MATE
※ 最後の接続確認はMacから実施しています。
構成図
Cloud9 (AWS) で実施する手順
1. Cloud9を構築する
環境の名前や説明はお好みで付ければOKです。
以下の画像の通り、Environment typeをEC2、PlatformをUbuntu Server 18.04 LTSとして構築します。
Point: 何故Amazon Linuxにしないのか
ここでAmazon Linuxを選んでも良いのですが、2020年1月の時点では、以下の理由で推奨しません。
- ここでAmazon Linuxを選択しても、Amazon Linux 2にはなりませんので、公式チュートリアルの手順でデスクトップ環境を作ることができません。
- Amazon Linux 2でCloud9を構築するにはSSH環境にする必要がありますが、SSH環境では一定時間操作がない時の自動停止機能が使えないので、私のようなズボラな方にはお勧めできません。
- Amazon Linuxは、2020年6月にサポートが終了します。
Q: Amazon Linux AMI はどれくらいの期間、サポートされますか?
AWS では 2020 年 6 月 30 日まで、Amazon Linux AMI 2018.03 の最新バージョンに対するセキュリティ更新の提供を継続し、Amazon Linux 2 への移行を促進します。Amazon Linux 2 では、2023 年 6 月 30 日まで長期サポートを受けることができます。2. デフォルトで作成されたEBSを拡張する
早速Cloud9に接続してデスクトップ環境をインストールしたいところですが、何もしないままにこの後紹介する手順でインストールを進めると、デフォルトで作成されるEBSボリュームの容量 (10GB) では不足してしまい、インストールが失敗します。
そこで、EBSボリュームを 10GB → 15GB に拡張します。
まずはAWSのマネジメントコンソールで、ボリュームの変更を行い、容量を拡張します。次に、拡張したEBSの容量を、OS上でも認識させます。
Cloud9のマネジメントコンソールを開き、ターミナルのウインドウで操作します。まず
lsblk
でパーティションを確認すると、拡張すべきパーティションが/dev/nvme0n1の1番目(MOUNTPOINTが/)だと分かりますので、sudo growpart /dev/nvme0n1 1
を実行して拡張します。
上記の実行後、パーティションを拡張した結果をlsblk
で確認すると、15GBになっていることが分かります。
次にdf -h
でファイルシステムを確認し、拡張すべきファイルシステムが/dev/nvme0n1p1だと分かりますので、sudo resize2fs /dev/nvme0n1p1
を実行して拡張します。
上記の実行後、ファイルシステムを拡張した結果をdf -h
で確認すると、15GBになっていることが分かります。コマンドは以下の通りとなります。
bashubuntu:~/environment $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 12.7M 1 loop /snap/amazon-ssm-agent/495 loop1 7:1 0 87.9M 1 loop /snap/core/5328 loop2 7:2 0 89.1M 1 loop /snap/core/8268 nvme0n1 259:0 0 15G 0 disk └─nvme0n1p1 259:1 0 10G 0 part / ubuntu:~/environment $ sudo growpart /dev/nvme0n1 1 CHANGED: partition=1 start=2048 old: size=20969439 end=20971487 new: size=31455199,end=31457247 ubuntu:~/environment $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 12.7M 1 loop /snap/amazon-ssm-agent/495 loop1 7:1 0 87.9M 1 loop /snap/core/5328 loop2 7:2 0 89.1M 1 loop /snap/core/8268 loop3 7:3 0 18M 1 loop /snap/amazon-ssm-agent/1480 nvme0n1 259:0 0 15G 0 disk └─nvme0n1p1 259:1 0 15G 0 part / ubuntu:~/environment $ df -h Filesystem Size Used Avail Use% Mounted on udev 468M 0 468M 0% /dev tmpfs 96M 764K 96M 1% /run /dev/nvme0n1p1 9.7G 7.6G 2.1G 79% / tmpfs 479M 0 479M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/loop0 13M 13M 0 100% /snap/amazon-ssm-agent/495 /dev/loop1 88M 88M 0 100% /snap/core/5328 tmpfs 96M 0 96M 0% /run/user/1000 /dev/loop2 90M 90M 0 100% /snap/core/8268 /dev/loop3 18M 18M 0 100% /snap/amazon-ssm-agent/1480 ubuntu:~/environment $ sudo resize2fs /dev/nvme0n1p1 resize2fs 1.44.1 (24-Mar-2018) Filesystem at /dev/nvme0n1p1 is mounted on /; on-line resizing required old_desc_blocks = 2, new_desc_blocks = 2 The filesystem on /dev/nvme0n1p1 is now 3931899 (4k) blocks long. ubuntu:~/environment $ df -h Filesystem Size Used Avail Use% Mounted on udev 468M 0 468M 0% /dev tmpfs 96M 764K 96M 1% /run /dev/nvme0n1p1 15G 7.6G 7.0G 53% / tmpfs 479M 0 479M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/loop0 13M 13M 0 100% /snap/amazon-ssm-agent/495 /dev/loop1 88M 88M 0 100% /snap/core/5328 tmpfs 96M 0 96M 0% /run/user/1000 /dev/loop2 90M 90M 0 100% /snap/core/8268 /dev/loop3 18M 18M 0 100% /snap/amazon-ssm-agent/1480ここまでの手順で、EBSの容量を 10GB → 15GB に拡張できました。
3. デスクトップ環境 (MATE) をインストールする
以下のコマンドを実行するだけです。
bashubuntu:~/environment $ sudo apt install ubuntu-mate-desktop4. vnc4serverをインストールして設定する
Cloud9にリモートデスクトップするために、以下のコマンドで、vnc4serverをインストールします。
bashubuntu:~/environment $ sudo apt install vnc4serverインストールが完了したら、以下のコマンド
vncserver :1
を実行し、一度VNCサーバを起動します。
コマンドを実行すると、デスクトップ環境にログインするためのパスワードの設定を求められますので、入力して設定します。
このパスワードは6文字以上8文字以下となり、8文字以上入力した時は、8文字目までがパスワードとして設定されます。bashubuntu:~/environment $ vncserver :1 You will require a password to access your desktops. Password: Verify: Password too long - only the first 8 characters will be used xauth: file /home/ubuntu/.Xauthority does not exist New 'ip-172-31-43-50:1 (ubuntu)' desktop is ip-172-31-43-50:1 Creating default startup script /home/ubuntu/.vnc/xstartup Starting applications specified in /home/ubuntu/.vnc/xstartup Log file is /home/ubuntu/.vnc/ip-172-31-43-50:1.log起動が完了したら、すぐVNCサーバを停止します。
bashubuntu:~/environment $ vncserver -kill :1 Killing Xvnc4 process ID 1058次に、一度起動したことによって、VNCサーバの設定ファイル
/home/ubuntu/.vnc/xstartup
が生成されていますので、この設定ファイルをMATE用に編集します。bash$ vi /home/ubuntu/.vnc/xstartup
設定ファイルの中身を、以下の内容に編集して保存します。
/home/ubuntu/.vnc/xstartup#!/bin/sh # Uncomment the following two lines for normal desktop: # unset SESSION_MANAGER # exec /etc/X11/xinit/xinitrc unset DBUS_SESSION_BUS_ADDRESS export XMODIFIERS="@im=fcitx" fcitx [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources xsetroot -solid grey # vncconfig -iconic & # x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & # x-window-manager & mate-session &5. vnc4serverの自動起動を設定
Cloud9を起動した時に、vnc4serverも自動起動するようにします。
~/.bashrc
を開き、最下行に起動コマンドを追記します。bashubuntu:~/environment $ vi ~/.bashrc
以下のように、最下行に起動コマンドを追記して保存します。
オプションの-geometry
は解像度、-depth
はビットカラー (8: 256色、16: 最大65536色、24: 最大16777216色)を示しますので、リモートデスクトップするクライアントの環境に合わせて変えてください。~/.bashrc# .bashrc export PATH=$PATH:$HOME/.local/bin:$HOME/bin (中略) # Add RVM to PATH for scripting. Make sure this is the last PATH variable change. export PATH="$PATH:$HOME/.rvm/bin" # ここから追記 vncserver :1 -geometry 1280x800 -depth 24保存後、OSを再起動します。
bashubuntu:~/environment $ sudo shutdown -r nowCloud9のマネジメントコンソール上に 「Connecting...」と表示されますので、自然に消えるのを待った後、次の手順に進みます。
6. SSHポートフォワードするため、パスワード認証を有効にする
デスクトップ環境にはインターネット経由で接続することになりますので、SSHポートフォワードを利用して、暗号化されたセキュアな接続にします。
Cloud9をubuntuユーザで利用する場合が殆どだと思いますので、デスクトップ環境もubuntuユーザで接続できるようにします。まず、ubuntuユーザのパスワードを設定します。
bash$ sudo passwd ubuntu Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully次に、
/etc/ssh/sshd_config
ファイルを編集し、PasswordAuthenticationのパラメータをyesに更新して保存します。bashubuntu:~/environment $ sudo vi /etc/ssh/sshd_config/etc/ssh/sshd_config(中略) # To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes #PermitEmptyPasswords no (中略)保存後、SSHのサービスを再起動します。
bashubuntu:~/environment $ sudo service ssh restart7. Security Groupで22番ポートを開放
クライアントPCからSSHポートフォワードを利用してリモートデスクトップするために、Cloud9のEC2インスタンスにアタッチされているSecurity Groupで22番ポートを開放します。
必ずクライアント側のグローバルIPを指定して/32で開放します。
開放すべきIPアドレスが分からない場合は、プルダウンで「マイIP」を選ぶと自動的に入力されます。
ここまでがCloud9側 (AWS側) の設定です。
クライアントPC側の設定
1. ターミナルからSSHポートフォワードする
AWSマネジメントコンソールでCloud9のEC2インスタンスにアタッチされたパブリックIPアドレスを確認し、クライアントPC側のターミナルで以下のコマンドを実行します。
以下のコマンドを実行した後、localhostの8888番ポートに接続すると、SSH経由でxxx.xxx.xxx.xxx(Cloud9)の5901番ポートに接続されます。bash$ ssh -L 8888:localhost:5901 ubuntu@xxx.xxx.xxx.xxx2. リモートデスクトップする
Macでは、Finderで「サーバへ接続」を開き、以下の通り入力して接続します。
接続すると、以下のようにデスクトップが開きます。
ここまでの手順で、Cloud9にデスクトップ環境をインストールして、クライアントからリモートデスクトップ接続ができました。
Cloud9でWebサーバを起動し、リモートデスクトップで動作確認する
Cloud9のMATEデスクトップ環境上のブラウザ (Firefox) を利用して、localhostに接続して動作確認できるかどうか試してみます。
まず、Cloud9でhttpd (Apache) を起動して、/var/www/htmlにテストファイルを置きます。
その後、リモートデスクトップでCloud9に接続して、ブラウザを開いて接続します。
このように、ブラウザを必要とする動作確認も、Cloud9のEC2インスタンス内だけで完結しますので、Cloud9で開発や検証を進める際の不便が一つ解消します。
- 投稿日:2020-01-04T22:26:52+09:00
AWS CloudWatch Logsで例外のログを取得する
現在勤めている企業ではDjangoで開発したアプリケーションをDocker Composeを利用して運用しています。
Dockerのログは以下のコマンドで確認することができます。
# appコンテナのログエントリーを表示し続ける(-fオプションでtail) $ docker-compose logs -f app # appコンテナの直近の500件のログエントリーを表示する $ docker-compose logs --tail=500 appしかし、運用していると、様々なトラブルがあって、トラブルの都度コンテナを実行しているサーバーにログインして、コンテナのログを確認するのが面倒臭い。
また、コンテナを破棄すると、今までのログも破棄してしまうため、運用環境では外部のログ保存ソフトウェアにログを送って保存します。Docker Composeではlog driverを利用することで、fluentdやAWS、GCPにログの送信・保存を行うことができます。
現在アプリケーションはAWSで運用しているので、以下の1〜3を行い、AWS CloudWatch Logsにログを送ることにします。
1. EC2インスタンスにIAMロールを設定 2. CloudWatch Logsでロググループを作成 3. docker-compose.ymlを修正1. EC2インスタンスにIAMロールを設定
コンテナを実行しているEC2インスタンスに以下のIAMロールを作成し設定する。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" } ] }参考:
Amazon CloudWatch Logs ロギング・ドライバ2. CloudWatch Logsでロググループを作成
AWSのコンソールでCloudWatchにアクセスし、ログ-->ロググループで「アクション」ボタンを押下します。そして、表示したダイアログにロググループ名を入力し、「ロググループの作成」ボタンを押下し作成します。
3. docker-compose.ymlを修正
以下の設定をdocker-compose.ymlに追記します。
docker-compose.ymlversion: '3' services: app: ・・・(中略)・・・ logging: driver: "awslogs" options: awslogs-region: "us-east-2" # オハイオリージョン awslogs-group: "/sample-app/dev/" awslogs-create-group: "true" # グループがない場合は作成 awslogs-stream: "web"以下のようにCloudWatch logsに保存できるようになりました。
ログをCloudWatch logsに保存できるようになったのは良いですが、例外が発生した場合、ログが以下のように1行ずつ分割してしまい非常に見づらくなってしまいました。例外が発生したスタックトレースも1行ずつ分割しないで1行で保存するようにします。
docker-compose.ymlに「awslogs-multiline-pattern」を追加します。またログを構造化してCloudWatch上で検索しやすくするために、django-structlogというモジュールをインストールします。django-structlogについては参考をご参照下さい。
docker-compose.ymlversion: '3' services: app: ・・・(中略)・・・ logging: driver: "awslogs" options: awslogs-region: "us-east-2" # オハイオリージョン awslogs-group: "/sample-app/dev/" awslogs-create-group: "true" # グループがない場合は作成 awslogs-stream: "web" awslogs-multiline-pattern: '^{"request_id":'以下のように例外も1行のログとしてCloudWatch Logsに保存できるようになりました。
- 投稿日:2020-01-04T22:03:21+09:00
AWS Cognitoで認証したユーザのID トークンを Java で検証する
やりたいこと
AWS Amplify の Authentication で認証したクライアントが id_tokenをサーバに送信し、Javaで実装したサーバで id_token を検証します。
TL;DR
- 発行者(ペイロードのiss) が対象にしている Cognitoのユーザプールであることを確認する。
- 署名の検証は https://github.com/auth0/java-jwt に丸投げ。
- com.auth0.jwt.JWTVerifier はスレッドセーフなのを前提にして、Cognitoが署名に使用した RSA鍵ペアを取得する回数を減らすために自前でキャッシュする。
実装
IdTokenValidator.java
IdTokenValidator.javapackage com.exampleawsCognito.jwt; import java.net.MalformedURLException; import java.net.URL; import java.security.interfaces.RSAPublicKey; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import com.auth0.jwk.GuavaCachedJwkProvider; import com.auth0.jwk.Jwk; import com.auth0.jwk.JwkException; import com.auth0.jwk.UrlJwkProvider; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; /** * Cognitoで認証して得られるid tokenを扱う * * <p> * 実装の参考にしたソース * https://github.com/awslabs/cognito-proxy-rest-service/blob/master/src/main/kotlin/com/budilov/cognito/services/CognitoService.kt * </p> * * @ThreadSafe * */ public class IdTokenValidator { private static final String AWS_REGION = "ap-northeast-1"; private static final String AWS_COGNITO_USER_POOL_ID = "my_userpool_id"; private static JWTVerifier verifier = null; private static long verifierExpire = -1; private static final long VERIFIER_LIVE_MILISEC = 10 * 60 * 1000; //10分 private static final JWT JWT = new JWT(); /** * コンストラクタ */ public IdTokenValidator() { } /** * IDトークン を検証します * * @param idToken 検証対象のIDトークン * @return 検証に成功した場合は ID Tokenのペイロード * * @throws InvalidTokenException ID Tokenの値が不正なので認証に失敗した */ public DecodedJWT verify(String idToken) throws InvalidTokenException { DecodedJWT decodedToken = JWT.decodeJwt(idToken); // cognitoのユーザプールで署名された事を確認する String iss = decodedToken.getIssuer(); if (!jwtTokenIssuer().equals(iss)) { throw new InvalidTokenException("ID トークンの発行者が対象のシステムではありません。iss=" + iss, idToken); } // ID トークンの用途が「ID」であることを確認します。 String tokenUse = decodedToken.getClaim("token_use").asString(); if (!"id".equals(tokenUse)) { throw new InvalidTokenException("ID トークンの用途が ID ではありません。token_use=" + tokenUse, idToken); } // 署名のアルゴリズムを確認します。 String alg = decodedToken.getAlgorithm(); if (!"RS256".equals(decodedToken.getAlgorithm())) { throw new InvalidTokenException("ID トークンの署名アルゴリズムが対応していないものです。alg =" + alg, idToken); } // payloadと署名を検証します。 DecodedJWT decodedJWT = null; if ((decodedJWT = tokenVerify(decodedToken)) == null) { throw new InvalidTokenException("ID Tokenの検証に失敗しました。", idToken); } return decodedJWT; } /** * auth0の のライブラリを利用して 検証を行う * * @param kid ID トークンのヘッダーにある キーID * @return nullでなければ デコードされた ID トークン * * @throws InvalidTokenException 検証に失敗した */ private DecodedJWT tokenVerify(DecodedJWT jwToken) throws InvalidTokenException { try { DecodedJWT verified = getVerifier(jwToken.getKeyId()).verify(jwToken); return verified; } catch (Exception e) { throw new InvalidTokenException(e); } } /** * JWTVerifier のインスタンスを取得する。 * * <p> * JWTVerifier は ver.3 からスレッドセーフになったので再利用する。 * ただし、署名に使われた RSAキーペアが更新される可能性を考えて、定期的に更新する * </p> * * @param kid 署名に使われたキーID * * @return * * @throws MalformedURLException * @throws JwkException */ private JWTVerifier getVerifier(String kid) throws MalformedURLException, JwkException { if (verifier != null && System.currentTimeMillis() < verifierExpire) { // 有効期限内ならそのまま使う return verifier; } synchronized (JWT) { // ロックを獲得したので念のためにもう一度確認してからインスタンスを生成する if (verifier != null && System.currentTimeMillis() < verifierExpire) { return verifier; } UrlJwkProvider http = new UrlJwkProvider(new URL(jwksUrl())); GuavaCachedJwkProvider provider = new GuavaCachedJwkProvider(http); Jwk jwk = provider.get(kid); Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null); verifier = JWT.require(algorithm) .withIssuer(jwtTokenIssuer()) .build(); // JWTVerifier の寿命を延ばす verifierExpire = System.currentTimeMillis() + VERIFIER_LIVE_MILISEC; Calendar expire = GregorianCalendar.getInstance(); expire.setTimeInMillis(verifierExpire); Logger.info("JWTVerifierのインスタンスを生成しました。期限は" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(expire.getTime())); } return verifier; } /** * ID トークンの発行者を取得します * * @return */ private String jwtTokenIssuer() { return String.format("https://cognito-idp.%s.amazonaws.com/%s", AWS_REGION, AWS_COGNITO_USER_POOL_ID); } /** * JSON Web トークン (JWT) セットのURLを取得します。 * * @return */ private String jwksUrl() { return jwtTokenIssuer() + "/.well-known/jwks.json"; } }
InvalidTokenException.java
InvalidTokenException.classpublic class InvalidTokenException extends Exception { public InvalidTokenException(String message, String idToken) { super(message + " token is " + idToken); } public InvalidTokenException(Throwable e) { super(e); } }使う側try{ // TODO IdTokenValidator はスレッドセーフなので static にする DecodedJWT payload = new IdTokenValidator().verify(idToken); String cognitoUserName = payload.getClaim("cognito:username").asString(); // 必要な処理 }catch (InvalidTokenException e) { Logger.error("ID トークンの検証に失敗しました", e); badRequest("IdTokenの値が不正ですよ"); }参考
- https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
- https://aws.amazon.com/jp/premiumsupport/knowledge-center/decode-verify-cognito-json-token/
- https://qiita.com/ya-mada/items/154ea6e10f9f788bfdd5
- https://openid.net/developers/jwt/
- http://openid-foundation-japan.github.io/rfc7517.ja.html
- https://github.com/awslabs/cognito-proxy-rest-service/blob/master/src/main/kotlin/com/budilov/cognito/services/CognitoService.kt
- 投稿日:2020-01-04T18:54:02+09:00
[初心者コピペ用]LaravelをAWSのEC2へデプロイ
前提
- 2020年1月4日に確認したものです。
- AWSのアカウント作成済
- プロジェクトをGitHubにpush済
環境
- macOS Catalina 10.15.2
- Apache 2.4
- PHP 7.1.33
- MySQL 5.7
- Laravel 5.8
1. EC2インスタンスの起動
- EC2コンソールで作成(「公式チュートリアル」が分かりやすかったです)
- 基本的に無料利用枠(下記の項目以外はデフォルト値)
設定項目 設定した内容 Amazon マシンイメージ (AMI) Amazon Linux 2でなく、Amazon Linux インスタンスタイプ t2.micro
Linux2だと、手順が異なる(公式ドキュメント)
インスタンス作成の最後に、SSH接続に必要なキーペアを生成or設定
キーペア(pemファイル)は、~/.sshフォルダに入れておくと良い
2. EC2内で作業
2-1. SSHでEC2に接続
SSHとは. SSH(Secure Shell)とは、安全に通信を行って、ネットワークに接続された機器を遠隔操作するための通信手段(プロトコル)の1つ
※ 参照:初心者がSSHについて学ぶ(´・ω・`)
$ ssh -i [キーペア(pemファイル)を置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]
iオプション
で、上記で生成or設定したpemファイルを指定するec2-user
は、デフォルトのユーザー名。最初はこのユーザー名を使うパブリックDNS or パブリックIP
は、EC2コンソール画面で確認できる- 初回接続時のみ、yes/noを聞かれる
2-2. Apache, PHP, MySQLのインストール
- yumのアップデートは忘れずに!(パッケージを最新にする)
- yumは
yオプション
を付けることで、問い合わせ全てにYesと答えるため、yes/noがいちいち聞かれなくなります。$ sudo yum update -y $ sudo yum install -y httpd24 php71 php71-mbstring php71-zip php71-fpm php71-mysqlnd mysql57-server2-3. Apacheを起動
$ sudo service httpd start※ Linux2だと、systemctlコマンドが使える
この時点で、ブラウザで
パブリック IP
にアクセスすると、Apacheの画面が表示される。
(EC2コンソール画面のセキュリティグループのインバウンドで、httpの80ポートを空けておくことを忘れずに)
# システムが再起動するたびにApacheが起動するように設定 $ sudo chkconfig httpd on # 設定の確認 $ chkconfig --list httpd2-4. ec2-userのファイル操作の許可を設定
参照:公式チュートリアル
Amazon Linux Apache ドキュメントルートは /var/www/html であり、デフォルトでは root によって所有されます。
そのため、ec2-userにファイル操作の権限を設定する必要がある。
# ec2-userをapacheグループに追加 $ sudo usermod -a -G apache ec2-user # いったんログアウトして、再度ログイン $ exit $ ssh -i [キーペアのpemファイルを置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP] # /var/www とそのコンテンツのグループ所有権を apache グループに変更 $ sudo chown -R ec2-user:apache /var/www # グループに、/var/wwwの書き込み許可追加 $ sudo chmod 2775 /var/www # /var/www とサブディレクトのディレクトリ許可を変更 $ find /var/www -type d -exec sudo chmod 2775 {} \; # /var/www とサブディレクトリのファイル許可を変更 $ find /var/www -type f -exec sudo chmod 0664 {} \;2-5. composer自身のインストール
& curl -sS https://getcomposer.org/installer | php # composerコマンドのパスを通す $ sudo mv composer.phar /usr/local/bin/composer # パス確認(/usr/local/bin/composerと表示されればOK) $ which composer2-6. Laravelプロジェクトをgit clone
sudo yum install git cd /var/www git clone [URL]2-7. Apacheの設定変更
http.confファイルのDocumentRootの変更
Laravelでは、プロジェクト内のpublicディレクトリをドキュメントルートに指定する必要がある
$ sudo vi /etc/httpd/conf/httpd.conf
DocumentRoot “/var/www/html”
の箇所をDocumentRoot “/var/www/プロジェクト名/public”
に変更http.confファイルに以下のDirectoryを追加(.htaccessの有効化)
<Directory /var/www/プロジェクト名/public> AllowOverride All </Directory>Apacheの設定変更後は、再起動を忘れずに!
$ sudo service httpd restart2-8. パッケージのインストール
$ cd /var/www/[プロジェクトのフォルダ名] # composer.jsonファイルがない場合 $ composer init # vendorディレクトリが生成される $ composer install2-9. Laraveプロジェクトの設定
ディレクトリのパーミッション変更
Laravelでは、
storage
下とbootstrap/cache
ディレクトリをWebサーバから書き込み可能にする必要がある$ sudo chmod -R 777 /var/www/[プロジェクト名]/storage $ sudo chmod -R 775 /var/www/[プロジェクト名]/bootstrap/cache.envファイルの作成
cp .env.example .env # .envファイルにある「APP_KEY」(アプリケーションキー)の生成 php artisan key:generateAPP_NAME=Laravel APP_ENV=production APP_KEY=base64:xxxxxxx(php artisan key:generateで生成される) APP_DEBUG=false APP_URL=http://[パブリックIP]2-10. DBの設定、作成
MySQL側
# MySQL起動 $ sudo service mysqld start # MySQLの初期設定 $ sudo mysql_secure_installation # システムが再起動するたびにMySQLが起動するように設定 $ sudo chkconfig mysqld on # データベース作成 $ mysql -u root -p > 設定したパスワード入力 > create database [データベース名]; > show databases;
mysql_secure_installation
コマンドで聞かれること
- パスワード検証プラグインのセットアップ
- パスワード
- 匿名ユーザーアカウントの削除
- rootユーザーのリモートログインの許否
- testデータベースの削除
Laravel側
# 「DB_DATABASE」など、DB情報を設定しておく $ sudo vi .env DB_DATABASE=[作成したデータベース名] DB_USERNAME=root DB_PASSWORD=[設定したパスワード]$ php artisan migrate $ php artisan db:seed参考にさせて頂いた記事
【Laravel】AWSにLaravelをインストールする
Laravel:EC2-PHP72-Apacheで環境を作成する
MySQL5.7 にて root のパスワード変更などの初期設定をする
- 投稿日:2020-01-04T18:54:02+09:00
LaravelをAWSのEC2へデプロイしてみた
前提
- 2020年1月4日に確認したものです。
- AWSのアカウント作成済
- プロジェクトをGitHubにpush済
環境
- macOS Catalina 10.15.2
- Apache 2.4
- PHP 7.1.33
- MySQL 5.7
- Laravel 5.8
1. EC2インスタンスの起動
- EC2コンソールで作成(「公式チュートリアル」が分かりやすかったです)
- 基本的に無料利用枠(下記の項目以外はデフォルト値)
設定項目 設定した内容 Amazon マシンイメージ (AMI) Amazon Linux 2でなく、Amazon Linux インスタンスタイプ t2.micro
Linux2だと、手順が異なる(公式ドキュメント)
インスタンス作成の最後に、SSH接続に必要なキーペアを生成or設定
キーペア(pemファイル)は、~/.sshフォルダに入れておくと良い
2. EC2内で作業
2-1. SSHでEC2に接続
SSHとは. SSH(Secure Shell)とは、安全に通信を行って、ネットワークに接続された機器を遠隔操作するための通信手段(プロトコル)の1つ
※ 参照:初心者がSSHについて学ぶ(´・ω・`)
$ ssh -i [キーペア(pemファイル)を置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP]
iオプション
で、上記で生成or設定したpemファイルを指定するec2-user
は、デフォルトのユーザー名。最初はこのユーザー名を使うパブリックDNS or パブリックIP
は、EC2コンソール画面で確認できる- 初回接続時のみ、yes/noを聞かれる
2-2. Apache, PHP, MySQLのインストール
- yumのアップデートは忘れずに!(パッケージを最新にする)
- yumは
yオプション
を付けることで、問い合わせ全てにYesと答えるため、yes/noがいちいち聞かれなくなります。$ sudo yum update -y $ sudo yum install -y httpd24 php71 php71-mbstring php71-zip php71-fpm php71-mysqlnd mysql57-server2-3. Apacheを起動
$ sudo service httpd start※ Linux2だと、systemctlコマンドが使える
この時点で、ブラウザで
パブリック IP
にアクセスすると、Apacheの画面が表示される。
(EC2コンソール画面のセキュリティグループのインバウンドで、httpの80ポートを空けておくことを忘れずに)
# システムが再起動するたびにApacheが起動するように設定 $ sudo chkconfig httpd on # 設定の確認 $ chkconfig --list httpd2-4. ec2-userのファイル操作の許可を設定
参照:公式チュートリアル
Amazon Linux Apache ドキュメントルートは /var/www/html であり、デフォルトでは root によって所有されます。
そのため、ec2-userにファイル操作の権限を設定する必要がある。
# ec2-userをapacheグループに追加 $ sudo usermod -a -G apache ec2-user # いったんログアウトして、再度ログイン $ exit $ ssh -i [キーペアのpemファイルを置いた場所のパス] ec2-user@[パブリックDNS or パブリックIP] # /var/www とそのコンテンツのグループ所有権を apache グループに変更 $ sudo chown -R ec2-user:apache /var/www # グループに、/var/wwwの書き込み許可追加 $ sudo chmod 2775 /var/www # /var/www とサブディレクトのディレクトリ許可を変更 $ find /var/www -type d -exec sudo chmod 2775 {} \; # /var/www とサブディレクトリのファイル許可を変更 $ find /var/www -type f -exec sudo chmod 0664 {} \;2-5. composer自身のインストール
& curl -sS https://getcomposer.org/installer | php # composerコマンドのパスを通す $ sudo mv composer.phar /usr/local/bin/composer # パス確認(/usr/local/bin/composerと表示されればOK) $ which composer2-6. Laravelプロジェクトをgit clone
sudo yum install git cd /var/www git clone [URL]2-7. Apacheの設定変更
http.confファイルのDocumentRootの変更
Laravelでは、プロジェクト内のpublicディレクトリをドキュメントルートに指定する必要がある
$ sudo vi /etc/httpd/conf/httpd.conf
DocumentRoot “/var/www/html”
の箇所をDocumentRoot “/var/www/プロジェクト名/public”
に変更http.confファイルに以下のDirectoryを追加(.htaccessの有効化)
<Directory /var/www/プロジェクト名/public> AllowOverride All </Directory>Apacheの設定変更後は、再起動を忘れずに!
$ sudo service httpd restart2-8. パッケージのインストール
$ cd /var/www/[プロジェクトのフォルダ名] # composer.jsonファイルがない場合 $ composer init # vendorディレクトリが生成される $ composer install2-9. Laraveプロジェクトの設定
ディレクトリのパーミッション変更
Laravelでは、
storage
下とbootstrap/cache
ディレクトリをWebサーバから書き込み可能にする必要がある$ sudo chmod -R 777 /var/www/[プロジェクト名]/storage $ sudo chmod -R 775 /var/www/[プロジェクト名]/bootstrap/cache.envファイルの作成
cp .env.example .env # .envファイルにある「APP_KEY」(アプリケーションキー)の生成 php artisan key:generateAPP_NAME=Laravel APP_ENV=production APP_KEY=base64:xxxxxxx(php artisan key:generateで生成される) APP_DEBUG=false APP_URL=http://[パブリックIP]2-10. DBの設定、作成
MySQL側
# MySQL起動 $ sudo service mysqld start # MySQLの初期設定 $ sudo mysql_secure_installation # システムが再起動するたびにMySQLが起動するように設定 $ sudo chkconfig mysqld on # データベース作成 $ mysql -u root -p > 設定したパスワード入力 > create database [データベース名]; > show databases;
mysql_secure_installation
コマンドで聞かれること
- パスワード検証プラグインのセットアップ
- パスワード
- 匿名ユーザーアカウントの削除
- rootユーザーのリモートログインの許否
- testデータベースの削除
Laravel側
# 「DB_DATABASE」など、DB情報を設定しておく $ sudo vi .env DB_DATABASE=[作成したデータベース名] DB_USERNAME=root DB_PASSWORD=[設定したパスワード]$ php artisan migrate $ php artisan db:seed参考にさせて頂いた記事
【Laravel】AWSにLaravelをインストールする
Laravel:EC2-PHP72-Apacheで環境を作成する
MySQL5.7 にて root のパスワード変更などの初期設定をする
- 投稿日:2020-01-04T18:50:24+09:00
AWSサービスの要点まとめ EC2編
はじめに
AWSの認定試験を受験するにあたって、各AWSのサービスを幅広く理解する必要があったためサービスごとに抑えるべきポイント等をまとめてみました。
今回はEC2についてです。※情報は2019年12月31日時点のものになります。ご了承ください。
概要
- AWS上で起動する仮想サーバー
- 購入時に起動するインスタンスタイプを選択できる
- インスタンスタイプによって仮想サーバーのスペックが変わる(CPUやメモリなど)
- sshなどでログインする際にはキーペア(pemキー)が必要
料金
選択されたインスタンスタイプ、購入方法によって異なる
基本はインスタンスを起動させている時間(秒単位)に応じて料金が発生する購入方法
購入方法は以下になります。
オンデマンドインスタンス
- 割引なしでインスタンスを購入する方法
- 処理が中断して落ちない
リザーブドインスタンス
- オンデマンドよりも安い値段でインスタンスを購入する方法
- 処理が中断して落ちる可能性がある
ハードウェア占有インスタンス(Dedicated Instance)
- 独立したハードウェアを購入する方法 オンデマンドなどでは同じハードウェアで複数インスタンスが同居して購入される可能性がある
- 物理サーバーの選択は不可能
専用ホスト(Dedicated Hosts)
- 独立したハードウェアを購入する方法
- 物理サーバーの選択は可能
- BYOL(Bring Your Own License)型のソフトウェアライセンスを持ち込める
Saving Plan
- 1~3年で一定のCPU使用料で契約する方法
AMI
EC2を起動するためのテンプレートのようなもの
この事前にソフトウェアなどをインストールしたインスタンスを立ち上げたいときに便利
- AMIリストを取得するにはDescribeImagesを実行する
- 別のリージョンでAMIを使用する場合は、AMIを別のリージョンにコピーする必要がある
- AMIはS3に作成される
ネットワーク
ネットワーク関連についてまとめます。
プライベートIP
- EC2インスタンスを起動したサブネット内で割り当てられたIPアドレス
- 起動時に指定することができる
パブリックIP
- AWSによって割り当てられるグローバルIPアドレス
- EC2インスタンスが停止→起動をすると新しいグローバルIPアドレスが割り当てられる
- EC2インスタンスが再起動してもグローバルIPアドレスは変わらない
- EC2インスタンスからインターネットにアクセスする場合はパブリックIPが割り当てられるように設定する必要がある
Elastic IP
- AWSが用意したグローバルIPアドレス
- EC2インスタンスにアタッチする必要がある
- EC2インスタンスが再起動(停止→起動)しても同一のグローバルIPアドレスを利用できる
ENI(Elastic Network Interface)
- 仮想ネットワークインターフェース
- 複数のIPアドレスが割り当てられる
プレイスメントグループ
EC2同士の通信を高速化できるEC2のグループ設定
- EC2インスタンスは同じアベイラリティゾーンである必要がある
セキュリティグループ
EC2インスタンスのアクセス制限を行う機能
- EC2インスタンスへのアクセスの許可のみを管理する(拒否の指定はできない)
- インバウンドが許可されると自動的にアウトバウンドも許可される
- デフォルト設定ではインバウンドの許可がされていない状態(つまり、すべてのインバウンドは拒否される)
インスタンスメタデータ
curlで取得できるインスタンスの情報
curl http://(IPアドレス)/latest/meta-data/instance-idストレージ関連
EC2のストレージ関連についてまとめます。
インスタンスストア
EC2のローカルディスク
- EC2インスタンスが停止または削除されるとデータが削除される
- EC2インスタンスが休止中のときはデータが保持される
- インスタンスストアのデータを引き続き保持したい場合は、その時点のAMIを取得する方法が有効
EBS(Elastic Block Store)
EC2にアタッチできるブロックストレージ
- EC2を停止してもEBSは削除されない
- 同じリージョンであれば同じEC2インスタンスに複数のEBSをアタッチできる
- 同じEBSを複数のインスタンスに同時にアタッチできない
- EBS-backedインスタンスはインスタンスの停止と再開ができるが、Instance store-backedインスタンスではできない
- ボリュームを暗号化できる
- EBSスナップショットでバックアップを作成できる
EBSのボリュームタイプ
Provisioned IOPS SSD
- I/Oの負荷が大きくても耐えられる(データベース用途など)
- IOPSの性能を指定したボリュームを作成可能(追加料金)
汎用SSD
- コスパがいい汎用的なSSD
スループット最適化HDD
- 高いスループットが期待できるHDD
コールドHDD
- 性能は低いが安い
- 古いデータのバックアップなどに向いてる
マグネティック
- 旧世代のボリュームタイプ
※IOPSとスループットの違い
IOPSとは
- ストレージが1秒あたりに処理できるI/O(書き込み・読み込み)アクセスの数。
- 一般的にHDDは1分あたりの回転数(PRM)に制限があるためIOPSは低い
スループットとは
- 1秒間の最大データ転送量
EBS最適化インスタンス
EC2、EBS間の回線が専用回線で繋がっているインスタンス
ネットワークがボトルネックになっているときに有効
特定のインスタンスタイプでのみ対応しているので、すべてのインスタンスで利用可能なわけではない
その他の豆知識
- OSを再起動させたい時はReboot(再起動)を行う
- EC2インスタンスを起動する際に実行したいシェルスクリプトを指定することができる(ユーザーデータ)
- 投稿日:2020-01-04T17:37:33+09:00
AWSメモ
AWSメモ
初期設定
AWSのアカウントを作成できる
料金アラート設定VPCネットワークを構築
全体像
- パブリックサブネット(ワードプレス等)とはインターネットと通信できるサブネットのこと。一般的にブラウザで展開される申し込みフォームのWebサーバー等
- プライベートサブネット(DB等)とはインターネットと通信できないサブネットのこと。
AWSネットワークの概念
- リージョンの選択
- リージョンによって使えるサービスが異なる(アメリカが機能大い、日本の場合は東京がおすすめ(通信が早い))
- アベイラビリティゾーン
- 独立したデータセンターのこと
- 複数設置されている
- VPC
- インターネット上に仮想ネットワークを作成できるサービス
- とても重要なサービス
- サブネット
- VPCを細かく区切ったネットワーク
ネットワークのIPアドレスを決める
- IPアドレスとはインターネット上の住所
- 一意性
- 32ビットの整数値(2進数)→読みにくいので8ビットずつの4つの組みにわけ10進数で表示 2進数とは パソコン初心者講座
- IPアドレスにはパブリックとプライベートがある
- パブリックはインターネットに接続する際利用する。ICANNという団体が管理していて全て一意のアドレス
- プライベートはインターネットで使用されないアドレス。範囲が決まっていて一意でなくても良い
- IPアドレスの範囲
- ネットワーク部・ホスト部(可変)に区分けすることで範囲を表現できる
VPCを作成する
サブネットを作成
ルーティングを設定
- ルーターを通じてネットワークがどのIPアドレスにあるかを管理
- ルートテーブルは「宛先のIPアドレス」と「次のルーター(AWSではターゲット)」という書式で設定する
- local→自身のネットワーク(インターネットに接続できない)
- インターネットの接続にはインターネットゲートウェイの作成が必要
- ルートテーブルは各サブネットに対して設定できる。
- サブネットやインターネットゲートウェイ間にはルーターが動いている
ネットワーク設計で考慮すべきポイント
- プライベートIPアドレス範囲から指定する
- 作成後は変更できないので、大きめの設定(/28~/16、/16が推薦)
- オンプレミスや他VPCのレンジと重複いないように気をつける。
- 異なるシステムの場合はアカウントを分ける
- 同一システムの各環境は、VPCとアカウントどちらを分けるか?→同一アカウントで、VPCとリージョンを分けるのがよい(どちらでもよい)
参考
パブリックサブネットとプライベートサブネットの違い | システム担当の教科書【EC2】Webサーバーを構築
EC2インスタンスを設置する
- EC2とは
- AWSクラウド上の仮想サーバー。インスタンスというのはEC2から立てられたサーバーの事。
- 特徴
- 数分で起動し、1時間または秒単位の従量課金。
- サーバーの追加・削除、マシンスペック変更も数分で可能。
- OSより上のレイヤについては自由に設定できる。
- 作成手順
- AMIの選択
- AMIとは
- AmazonMachineImageの略。インスタンスに必要な情報が入ったOSのイメージ。
- インスタンスタイプの選択
- インスタンスタイプとは
- サーバーのスペックを定義したもの- インスタンスタイプにより、料金が異なる
- ストレージの追加
- サーバーにくっつけるデータの保管場所。EC2のストレージには2種類ある。
- 1.EBS(高い可用性と耐久力を持つストレージ、他のインスタンスに付け替え可能、EC2インスタンスをStop/TerminateしてもEBSは保持可能、Snapshotを取得しS3に保存可能、EBSの費用が別途発生、OSやDBなどの永続性と耐久性が必要なデータを置く)
- 2.インスタンスストア(インスタンス専用の一時的なストア、他のインスタンスに付け替えることができない、EC2インスタンスをStop/Terminateするとクリアされる、追加費用なし、なくなってはいけないデータは置かない、一時ファイル・キャッシュなどなど失われても問題ないデータを置く)
- セキュリティグループの設定
- SSHキーペアの設定
SSHについて
- サーバーにログインするとは
- 離れたところにあるサーバーにはいって、自分のパソコンから操作すること
- SSHでログインすると自分がまるでWebサーバーの目の前にいるかの様に自分のコンピューターからWebサーバーを操作できる。
- SSHとは
- サーバーにセキュアに接続する仕組み - 暗号化されている
公開会議認証について
- 誰でもサーバーに入れると困るので、サーバーの作成者本人だけがログインできるよう、EC2ではSSHログイン時に公開鍵認証を行なっている
- 公開鍵認証とは
- サーバーへのログイン時に認証を行う仕組み。
- ユーザー名とパスワード使用した認証と比べ、よりセキュリティが高い
- 公開鍵暗号(秘密鍵と公開鍵)を用いて認証を行う。
- 公開鍵はサーバーが保有。秘密鍵を持っているユーザーだけログイン可能。
- 公開鍵暗号の「暗号」とは?
- イメージは南京錠
SSHでECインスタンスに接続する
ポート番号について
- SSHでログインしてサーバーを操作できるのはなぜ?→ サーバー状でSSHぜつ族を受け入れコマンドを受け付けるプログラム(sshd)が動いているから
- サーバーにはたくさん起動しているプログラムがSSHのリクエストを受け付けるがどうやって選別しているのか?→ポート番号で選別している
- ポート番号はプログラムのアドレス。同一コンピューターで通信を行うプログラムを識別するときに利用される。
- 例)SSH:22
- どうやってポート番号を決めるか
- 2つキメ方がある。
- 1.標準で決められている番号
- ウェルノウンポート番号
- 代表的なプログラムが使うポート番号はあらかじめ決められている。
- 2.動的に決められている番号
- サーバーを提供する側(サーバー)はポート番号が決まっている必要があるが、クライアント側のポート番号は決まっていなくて良い
- クライアントのポート番号は、OSが他のポート番号と被らない様にランダムに決める。
[ec2-user@ip-10-0-10-10 ~]$ sudo lsof -i -n -P COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rpcbind 2689 rpc 6u IPv4 16847 0t0 UDP *:111 rpcbind 2689 rpc 7u IPv4 16848 0t0 UDP *:736 rpcbind 2689 rpc 8u IPv4 16849 0t0 TCP *:111 (LISTEN) rpcbind 2689 rpc 9u IPv6 16850 0t0 UDP *:111 rpcbind 2689 rpc 10u IPv6 16851 0t0 UDP *:736 rpcbind 2689 rpc 11u IPv6 16852 0t0 TCP *:111 (LISTEN) chronyd 2698 chrony 1u IPv4 17108 0t0 UDP 127.0.0.1:323 chronyd 2698 chrony 2u IPv6 17109 0t0 UDP [::1]:323 dhclient 2919 root 6u IPv4 17829 0t0 UDP *:68 dhclient 3036 root 5u IPv6 18138 0t0 UDP [fe80::4ab:97ff:fe52:17c]:546 master 3173 root 13u IPv4 19031 0t0 TCP 127.0.0.1:25 (LISTEN) sshd 3390 root 3u IPv4 20731 0t0 TCP *:22 (LISTEN) sshd 3390 root 4u IPv6 20740 0t0 TCP *:22 (LISTEN) sshd 4829 root 3u IPv4 108709 0t0 TCP 10.0.10.10:22->114.191.10.30:51866 (ESTABLISHED) sshd 4846 ec2-user 3u IPv4 108709 0t0 TCP 10.0.10.10:22->114.191.10.30:51866 (ESTABLISHED)(LISTEN)は待ち受けているポート
(ESTABLISHD)は通信中相手と通信中のポート
- Apacheをインストールする
Apacheとは
- 世界中で使用されているWebサーバーソフトウェア
- サーバーのにApacheをインストールすることでWebサーバーとしての機能(レスポンス等)ができるApacheとは?Webサーバーの仕組みと人気サーバーソフトを徹底解説 | カゴヤのサーバー研究室
アパッチ (Apache)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典[ec2-user@ip-10-0-10-10 ~]$ sudo yum update -yyumの更新
yum linuxのパッケージ管理ツール(インストールや更新等)
-y はyesオプション。[ec2-user@ip-10-0-10-10 ~]$ sudo yum -y install httpdhttpdはアパッチを構成する実行コマンド
[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl start httpd.service起動の確認
[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl enable httpd.serviceアパッチを自動起動設定する
- ファイアウォールを設定する
- ファイアウォールとは
- ネットワークを不正アクセスから守る為に「通してよい通信だけを通して、それ以外は通さない」機能の略称。
Elastic IPアドレスでIPアドレスを固定する
- ElasticIPアドレスとは EC2インスタンスのパブリックIPは、起動・停止すると別のIPアドレスが割り当てられる。ElasticIPアドレスを利用すると、IPアドレスを固定できる。
- 特徴
- そのインスタンスを削除するまでは、ずっとそのIPアドレスを使用することができる。
- ElasticIPアドレスは、EC2に関連付けられていて、そのインスタンスが起動中であれば無料。逆に起動してなければ課金される。
【Route53】ドメインを登録する
構築するもの
ドメイン名でWebサーバーにアクセスできるようにする
ドメインについて
www.example.co.jp
第4レベルドメイン.第3レベルドメイン.第2レベルドメイン.トップドメイン
ドメインレベルに応じて各組織が管理している。
ドメイン名でアクセスできる理由
DNSについて
- DNSとはドメイン名をIPアドレスに変換するもの
- ネームサーバーとフルリゾバの2つから構成されている
- ①ネームサーバー
- ドメイン名とそれに紐づくIPアドレスが登録されているサーバー
- ドメインの階層ごとにネームサーバーが配置され、そのネームサーバーが配置された階層のドメインに関する情報を管理する。
- ②フルリゾバ(秘書の様なもの)
- 「どのドメインに紐づくサーバーか教えて」とおい合わせると、色々なネームサーバーに聞いてIPアドレスを調べて教えてくれる。
Route53について
- Route53とは
- AWSのDNSサービス。ネームサーバーの役割を果たす。
- 重要概念
- ホストゾーン
- DNSのリソースレコードの集合。ゾーンファイルの様なもの
- ルーティングポリシー
- Route53がRecordSetに対してどの様にルーティングを行うかを決める
- シンプル、加重、レイテンシー、位置情報、フェイルオーバー等がある
- ヘルスチェック
- サーバーの稼働状況をチェック。
Route53でDNSを設定する
mbair:~ okadaatsuyoshi$ ssh -i ~/Desktop/aws-and-infra-ssh-key.pem ec2-user@52.196.118.157ec2へログイン
[ec2-user@ip-10-0-10-10 ~]$ dig aws-and-infraa.work NS +shortで現在のネームサーバーを確認。
現在はデフォルトでお名前.comのネームサーバーになっているので変更する。【RDS】DBサーバーを構築する
RDSについて
- AWSがフルマネージメントでDBの管理やってくれるので運用が楽。
複数のアベイラビリティーゾーンにプライベートサブネットを作成することが推奨されている。
- RDSとは
- フルマネージドなリレーショナルデータベース(いわゆるDB)のサービス。
- メリット
- - 構築の手間の軽減 - 運用の手間の軽減 - AWSエンジニアによるデータベース設計のベストプラクティスを適用 - ➡️コア機能の開発に注力できる
- 各種設定グループ
- DBパラメータグループ:DB設定値を制御
- DBオプショングループ:RDSへの機能追加を制御
- DBサブネットグループ:RDSを起動させるサブネットを制御
- 特徴
- 可用性の向上
- 複数のアベイラビリティゾーンを設定することで簡単にリスクを軽減
- パフォーマンスの工場が楽
- リードレプリカを簡単に構築
- 書き込みようのマスターと読み込み用のリードレプリカを別々で作成できるので読み込みの速度が向上向上
- 運用不可の軽減
- 自動バックアップ(1日1回スナップショット)
- リストア(スナップショットを元にDBインスタンスを作成)
- 自動的なソフトウェアメンテナンス
- メンテナンスウィンドウで指定した曜日・時間帯にアップデートを自動実施
- 各種メトリクスを60秒間隔で取得・確認可能
プライベーサブネットを作成
RDSを設置
RDSの作成準備
- セキュリティグループの作成(EC2)
- DBサブネットグループの作成
- DBパラメータグループの作成
- DBオプショングループの作成(機能を設定)
- 投稿日:2020-01-04T16:37:43+09:00
技術ブログはじめました
みなさん、はじめまして!
音楽とアニメとハイボールが大好きな Web エンジニアの yasu と申します!このたび、超個人的嗜好で厳選したお気に入りの音楽を Apple Music のプレイリスト形式で紹介していく音楽ブログ「Fav Music」の構築・運用過程で得た技術的知見を qiita にアウトプットさせていただくことにしました。
僕がここでアウトプットした技術情報がいつか誰かの助けになったら嬉しいです :)
今回はご挨拶がわりに僕が Fav Music を構築・運用するために使用している技術や製品をご紹介させていただきます。
なお、Fav Music の全てのソースコードは GitHub でも公開してますので興味のある方は合わせてご参照ください。
<(*_ _)>Fav Music を構築するために使用している技術や製品
- MacBook Early 2015
- macOS Catalina 10.15.2
- Git 2.21.0 (Apple Git-122.2)
- Homebrew 2.2.2
- Rbenv 1.1.2
- Ruby 2.6.5
- Jekyll 3.8.6
- Adobe XD 25.1.12.7
- Visual Studio Code 1.41
- Google Chrome 79.0.3945.88
- GitHub
使用した技術や製品をいろいろ列挙しましたけど、重要なのは Jekyll だけですね笑
今流行りの静的サイトジェネレーターってやつですw
最初は WordPress でサイトを構築したんですけど、静的サイトジェネレーターをいろいろ試してみて最終的に Jekyll にしました。
Jekyll の他にも
を試してみましたが、Jekyll を採用した決め手は、タグの一覧ページのページング機能が割と簡単に実現できたことです(各静的サイトジェネレーターのデフォルトの機能では意外と実現するのが難しい部分です)。
静的サイトジェネレーターで生成した静的サイトは WordPress で構築した動的サイトと比較してページングと検索の機能が弱い(というか自分で実装しないといけない)ので、これから静的サイトジェネレーターを使おうと思っている方はまず最初にその辺の使い勝手を徹底的に調査しておいた方がいいかもしれません。
ちなみに、Fav Music ではまだ検索機能は実装してません?
Adobe XD はキャッチアイ画像を作成するのに使ってるだけです。僕はデザインツールには詳しくないのでアレですが、Adobe XD はサクサク動いて使ってて気持ちいいですv
Visual Studio Code はコード(
HTML
,CSS
,JavaScript
,YAML
,Ruby
,Liquid
)と記事(Markdown
)を編集するのに使ってるのと、Git
とかShell
コマンドも内臓ターミナルから叩いてるので、ぶっちゃけほとんどこの中にいますwGoogle Chrome は、もちろん表示の確認とデバッグ(スタイルの調整)に使ってます。
Fav Music を運用するために使用している技術や製品
最初に WordPress でサイトを構築したときは EC2 と RDS と ALB を使ってガチで半年ほど運用してましたが、そもそも静的なコンテンツしかないんだから S3 で十分じゃね?ということに気付き、先日 S3 に切り替えました (笑)
これで万が一 Yahoo 砲が来ても耐えれますw
WordPress から S3 の静的 Web サイトホスティングに切り替える時にちょっと困ったことは、S3 ではページ URL の拡張子(
.html
)を省略できないっていうことでした(ディレクトリ URL のindex.html
は省略できます)。対策はいくつかあるみたいですが、僕は単純に内部リンクは拡張子(
.html
)付きで書いて、WordPress の時に使われていた拡張子なしの URL は新しい URL に Rewrite (S3 側にRedirection rules
として登録) するようにしました。このやり方が一番良いやり方だったとは思えないので、もう少し調べて別の記事にまとめたいと思ってます。
S3 + CloudFront でブログを運用した場合の実際のコスパについてもみなさん気になるところだと思うので近々公開したいと思ってますが、幸か不幸か全くアクセスがないサイトなので (恥)、参考になる数字が出せる日が来るかどうかは怪しいものです (笑)
まとめ
以上、僕が Fav Music を構築・運用するために使用している技術や製品をご紹介させていただきましたがいかがだったでしょうか。
今回は技術情報としてはほとんど価値のない記事だったと思うので、次回はもう少し役に立つ情報をアウトプットしたいと思います?
ではまた ( ⸝⸝•ᴗ•⸝⸝ )੭⁾⁾
- 投稿日:2020-01-04T16:02:19+09:00
AWS+NodeJSでサーバレスな環境構築④
はじめに
今回は前回の続きで、DELETE(対象ユーザーの削除), GET(全ユーザーの取得) PATCH(対象ユーザーの更新)を作っていきます。
DELETE(対象ユーザーの削除)
指定されたidを元に、対象のユーザーが削除されるようにしていきます。
Lambda関数の作成と設定
ソース
index.js'use strict'; const AWS = require('aws-sdk'); const myRegion = "us-east-2"; AWS.config.update({ region: myRegion}); exports.handler = async (event, context) => { const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion}); let responseBody = ""; let statusCode = 0; const { id } = event.pathParameters; const params = { TableName: "Users", Key: { id: id } }; try { const data = await documentClient.delete(params).promise(); responseBody = JSON.stringify(data); statusCode = 204; } catch (err) { responseBody = `Unable to delete user: ${err}`; statusCode = 403; } const response = { statusCode: statusCode, headers: { "Content-Type": "application/json" }, body: responseBody }; return response; };メソッド作成と設定
テスト実行と確認
GET(全ユーザーの取得)
GETメソッドを実行したとき、全ユーザーが取得されるようにする。
Lambda関数の作成と設定
index.js'use strict'; const AWS = require('aws-sdk'); const myRegion = "us-east-2"; AWS.config.update({ region: myRegion}); exports.handler = async (event, context) => { const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion}); let responseBody = ""; let statusCode = 0; const params = { TableName: "Users" }; try { const data = await documentClient.scan(params).promise(); responseBody = JSON.stringify(data); statusCode = 200; } catch (err) { responseBody = `Unable to get users: ${err}`; statusCode = 403; } const response = { statusCode: statusCode, headers: { "Content-Type": "application/json" }, body: responseBody }; return response; };メソッド作成と設定
テスト実行と確認
PATCH(対象ユーザーの更新)
PATCHメソッドを実行したとき、対象のユーザが更新されるようにする。
Lambda関数の作成と設定
メソッド作成と設定
テスト実行と確認
リクエスト本文{ "id": "02", "firstname": "update_firstname", "lastname": "update_lastname" }終わりに
これでサーバレスでREST APIを使ったCRUD作成の環境構築をしました。
次はAPI Gateway+Lambda(NodeJS)+S3を組み合わせていこうと思います。
kinesisやauroraあたりを組み合わせてやりたいです。
- 投稿日:2020-01-04T15:40:11+09:00
Fargate及びECSでコンテナからAWSのIAM認証を利用する
概要
AWSでコンテナを利用する場合、FargateやECSが候補に上がると思います。
コンテナからAWSの各種サービスを利用する場合、IAMのCredentialsを利用する必要があります。
いつも意識せずに利用しているIAMですが、裏ではどういう構成になっているのか確認していきます。確認方法
Fargateでsshできるようにして、コンテナ内でCredentialsを探します。
Fargateでsshするには以下の記事を参考にしてください
- https://qiita.com/pocari/items/3f3d77c80893f9f1e132
- https://qiita.com/ryurock/items/fa18b25b1b38c9a0f113
- https://qiita.com/fnaoto/items/c980efa39c2b1597331e
結果
Fargateでは
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
という環境変数にCredentialsへのファイルファイルパスが入っているようです。
- 詳細はこの記事を参考にしてください
rootユーザでコンテナにログインしても環境変数が設定されていない
実は、この環境変数はPIDが1のプロセスに設定されているようです
確認方法
$ strings /proc/1/environ
例えば、Dockerfileで以下のようになっている場合。
この場合、環境変数はPIDが1の/bin/sh
に設定されます。
そして、bundle exec rails s
には親プロセスの/bin/sh
から環境変数が引き継がれます。CMD ["/bin/sh", "-c", "bundle exec rails s"]ちなみに、以下のようにデーモンプロセスを動かす場合。
この場合は起動するデーモンの親プロセスは/bin/sh
にはならないので環境変数は引き継がれません。CMD ["/bin/sh", "-c", "service ssh start"]環境変数に設定されているIAMはどこから設定するのか
このIAMはTask Roleを参照しているようです。
なので、taskRoleArn
に設定しているIAMから権限を変更可能です。RubyライブラリでIAM認証を使う場合
aws-sdk-rubyでは以下のように、
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
があればECSCredentials.new
するようにしているみたいです。
ちなみに、instance_profile_credentialsはprivateなので外から呼び出しはできないみたいです。
普段、ライブラリを使う場合は特に意識することなくことなく、Credentialsが使われているようですね。# https://github.com/aws/aws-sdk-ruby/blob/704c4a2afbee1bb20a6c47545305684a92771f7e/gems/aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb#L110 def instance_profile_credentials(options) if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"] ECSCredentials.new(options) else InstanceProfileCredentials.new(options) end end
- 投稿日:2020-01-04T14:49:38+09:00
【AWS完全に理解したへの道】VPC 基本編
【AWS完全に理解したへの道】 IAM 基本編
に続く、VPC 基本編(項目の然るべき順序的なものは後で整理するかも)VPCの作成
ある特定のリージョンを選択してプライベートネットワーク空間を作成する。
プライベートネットワーク空間は /16(65,536個のIPアドレス)から /28(16個のIPアドレス)のCIDR(Classless Inter-Domain Routing)ブロック範囲で作成できる。VPCを作成する場合は、RFC1918に指定されているように、以下のプライベートIPv4アドレス範囲からCIDRブロックを指定することを推奨されている。
- 10.0.0.0 - 10.255.255.255
- 172.16.0.0 - 172.31.255.255
- 192.168.0.0 - 192.168.255.255
サブネット作成
サブネットを作成時、AZごとに1つ以上のサブネットを追加する必要がある。
サブネットはAZをまたがって作成することはできない。
また、VPC CIDRブロックのサブセットである、サブネットのCIDRブロックを指定する。オプション
IPv6 CIDRブロックをVPCに割り当てて、IPv6 CIDRブロックをサブネットに割り当てることができる。
ゲートウェイの作成
インターネットゲートウェイ(IGW)
できること
- インターネットでルーティング可能なトラフィックの送信先をVPCのルートテーブルに追加することができる。
- パブリックIPv4アドレスが割り当てられているインスタンスに対してNAT(ネットワークアドレス変換)を行うことができる。
バーチャルプライベートゲートウェイ(VGW)
VPNやオンプレのデータセンタなどと通信するための出入り口となるゲートウェイ。
EC2インスタンスのIPアドレス
VPCサブネット内で起動するEC2インスタンスにはそのサブネット内のプライベートIPアドレスが少なくとも一つ割り振られる。
そのEC2インスタンスにインターネットからアクセスしたい場合、さらにグローバルIPアドレスを割り振る必要がある。AWSのグローバルIPアドレスには以下の2種類がある。
- Public IP : EC2インスタンスが起動した際にランダムに割り振られる動的なグローバルIPアドレス。
- Elastic IP : アカウントに割り当てられる固定のグローバルIPアドレスでEC2インスタンスにアタッチ/デタッチする。 固定のグローバルIPアドレスでの運用が必要な場合に使用する。
※EC2インスタンスのプライベートIPアドレスとグローバルIPアドレスの紐付けはVPCの仮想ネットワークで行われる。
よって、EC2インスタンスのOSにログインしてifconfigコマンドなどでネットワークの設定を見てもプライベートIPアドレスの値しか表示されない。ルートテーブルの作成
各サブネットがパブリックなのか、プライベートなのかは各サブネットに適用されているルートテーブルによって決定される。
また、VPC内の通信はルートテーブルでは制御できない。パブリックサブネット
インターネットのアクセスを許可するサブネット
デフォルトゲートウェイのターゲットにIGW(インターネットゲートウェイ)が設定されたルートテーブルが適用されているサブネット。プライベートサブネット
インターネットのアクセスを許可しないサブネット
デフォルトゲートウェイのターゲットにIGWが設定されたルートテーブルが適用されていないサブネット。NATインスタンス
インターネットからのアクセスを受け付けないまま、プライベートサブネット内からインターネットやリージョンサービスにアクセスさせたいときに使用する。
- NATインスタンスの実態はEC2インスタンス。
- プライベートサブネット内のEC2インスタンスからトラフィックを受け付ける。
- そのEC2インスタンスのプライベートIPアドレスをNATインスタンスに割り振られたグローバルIPアドレスに変換し、インターネットへのアクセスを可能にする。
セキュリティグループ
EC2やELBやRDSなどのインスタンスごとのファイアーウォール。
各インスタンスごとに1つ以上のセキュリテイグループを適用する必要がある。ネットワークアクセスコントロール(ACL)
サブネットごとのファイアーウォール。
セキュリティグループとネットワークACLの違い
セキュリティグループ ネットワークACL 適用単位 EC2、ELB、RDSなどのインスタンス単位 サブネット単位 作成、追加可能なルール 許可のみ 許可/拒否 デフォルトルール インバウンド:全て拒否
アウトバンド:全て許可インバウンド:全て許可
アウトバンド:全て許可特徴 ステートフル ステートレス VPCピア接続
2つのVPCを接続する機能。
2つのVPC間でVPCピア接続を確立すると、双方のVPCにPCXというゲートウェイに相当するものが作成される。
VPCピア接続の制約条件は以下となる。
- 接続するVPCは同じリージョンに存在する必要がある。
- 接続するVPCのプライベートネットワークアドレス空間は重複しないようにする必要がある。
- 1 対 1の接続にする必要がある。
- 投稿日:2020-01-04T14:44:56+09:00
AWS+NodeJSでサーバレスな環境構築③
はじめに
前回の記事ではDynamoDBのテーブルと項目作成、Lambda関数で使うロールやインラインポリシーの設定を行いました。今回はその続きで、API Gateway(REST APIでCRUD実装)をトリガーにし、Lambda(NodeJS)関数呼び出して、DynamoDBに参照や更新をできるようにします。
表現等が不適切の場合はご指摘いただければ、幸いです。
※サーバレスに関してよくわからない方は、こちらをご覧いただければと思います。アーキテクチャ図
流れ
- ソースで直接(Api gatewayを使わず)参照や更新ができるかを確認
- POST(ユーザーの登録)
- domain.com/users/{id}
- DELETE(対象ユーザーの削除)
- domain.com/users/{id}
- GET(全ユーザーの取得)
- domain.com/users
- PATCH(対象ユーザーの更新)
- domain.com/users/{id}
ソースで直接(Api gatewayを使わず)参照や更新ができるかを確認
まずはLambda(NodeJS)でDynamoDBテーブルが参照・更新できるか確認
Lambdaダッシュボード>関数の作成>一から作成>以下の通り入力>関数の作成ボタン
※既存のロール設定は前回の記事で作成したものを使用しています。
データの参照ができるよう、ソース編集
こちらのリファレンスを参考にしました。index.js'use strict'; const AWS = require('aws-sdk'); const myRegion = "us-east-2"; AWS.config.update({ region: myRegion}); exports.handler = async (event, context) => { const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion}); //読込用のデータ const params1 = { TableName: "Users", Key: { id: "01" } }; //書込用のデータ const params2 = { TableName: "Users", Item: { id: "02", firstname: "first02", lastname: "last02" } }; try { const readData = await documentClient.get(params1).promise(); const writeData = await documentClient.put(params2).promise(); console.log(readData); console.log(writeData); } catch (err) { console.log(err); } };⚠️ 必ず、DynamoDBとLambdaは同じリージョンで作成するように気をつける。また上記ソースのmyRegion変数値も合わせるように気をつける。いずれが満たない場合、AccessDeniedExceptionという
意味不明なエラーが発生する可能性があります。テストイベントの設定(今回はgetUserData)>テストボタン>取得結果が表示されれば、OK
DynamoDBにデータ作成されていることを確認
ちなみに、params2でidをそのまま、firstnameやlastnameを変更すると更新される仕様です。
API Gatewayトリガー追加と設定
API Gatewayダッシュボード>APIを作成ボタン>REST APIの構築ボタン(Privateじゃない方)
以下のように入力>APIの作成ボタン
エッジ最適化について(AWS公式より引用)
エッジ最適化 API は、API ゲートウェイによって作成および管理される CloudFront ディストリビューション経由でアクセスするエンドポイントです。以前は、エッジ最適化 API は、API ゲートウェイを使用して API を作成する際のデフォルトオプションでした。
参考記事
・0からREST APIについて調べてみた
・エッジ最適化について説明リクエスト、レスポンスマッピングのモデルを作成及び設定
参考
モデル名、コンテンツタイプ、スキーマ(ソース)を設定します。
スキーマのソース{ "$schema": "http://json-schema.org/draft-04/schema#", "title": "UsersInputModel", "type": "object", "properties": { "id": {"type": "string"}, "firstname": {"type": "string"}, "lastname": {"type": "string"} } }POSTメソッド実装(ユーザーの登録)
ここではAPI GatewayでPOSTメソッドを作成して、レコードが登録されるかを確認する。
API Gatewayと紐付けるLambda関数を作成と設定
関数名はputUsersで、その他の設定は前回と一緒
(察して)(冒頭のLambda関数作成のスクリーンショット参照)以下のソースを貼り付けます。
DynamoDBの構成に関しては、こちらの記事を参考にしてください。(DynamoDBテーブルの作成部分)index.js'use strict'; const AWS = require('aws-sdk'); const myRegion = "us-east-2"; AWS.config.update({ region: myRegion}); exports.handler = async (event, context) => { const documentClient = new AWS.DynamoDB.DocumentClient({ region: myRegion}); let responseBody = ""; let statusCode = 0; const { id, firstname, lastname } = JSON.parse(event.body); const params = { TableName: "Users", Item: { id: id, firstname: firstname, lastname: lastname } }; try { const data = await documentClient.put(params).promise(); responseBody = JSON.stringify(data); statusCode = 201; } catch (err) { responseBody = `Unable to put user ${err}`; statusCode = 403; } const response = { statusCode: statusCode, headers: { "Content-Type": "application/json" }, body: responseBody }; return response; }POSTメソッド作成と設定
メソッドリクエストの設定
モデルの追加には上記の作成したモデルを追加する
API Gatewayで確認テスト
下の方にテストボタンあるので、それを押すとテスト結果(ログも含めて)画面右側に表示されると思います。
リクエスト本文{ "id": "03", "firstname": "first03", "lastname": "last03" }テストステータスで201が返ってこれば、成功みたいです。
⚠️ ちなみに本来DynamoDBテーブルにない項目論理名(例えばfirstnameではなく、あえてnickname)をリクエスト本文に設定された場合、問題なくテスト処理は実行されます。対象のレコードfirstnameには空白が入る仕様になっています。DynamoDBテーブルにレコードが作成されていることを確認
to be continued
ちょっと長くなりそうなので、続きを次回出します。
あとはDELETE(対象ユーザーの削除), GET(全ユーザーの取得) PATCH(対象ユーザーの更新)のメソッドを作成して、最後までCRUD機能を実装していきます。
- 投稿日:2020-01-04T02:24:47+09:00