はじめに
2017年の年末に「Macに別れを告げて、クラウド中心の開発生活を始めるまで」という投稿を読んで、強く刺激を受けました。私も「Chrome縛り」をしてみたい(されてみたい?)と思うようになりました。
今回、AWSの東京リージョンに新しくWebサーバーをたてるという仕事をいただき、なにはともあれ(クライアントの)新アカウントを使って、シンガーポールリージョンにAWS Cloud9を構築してみました。果たして、そこから東京リージョンのWebサーバーをコントロールすることができるのか? 以下はその報告です。
まずは、シンガポールリージョンにCloud9開発環境を構築する
作業そのものは簡単でした。「AWS Cloud9を動かしてみた」という投稿に書いてある通りです。
右下のBashコンソールを操作してみます。
sudo yum update -y
cat /etc/system-release
#=> Amazon Linux AMI release 2017.09
git --version
#=> git version 2.13.6
node -v
#=> v6.13.1
npm -v
#=> 3.10.10
python --version
#=> Python 2.7.13
pip --version
#=> pip 9.0.3 from /usr/local/lib/python2.7/dist-packages (python 2.7)
aws --version
#=> aws-cli/1.14.9 Python/2.7.13 Linux/4.9.91-40.57.amzn1.x86_64 botocore/1.8.13
予想していたとおり、普通のAmazon Linuxです。
今までもWebサーバーにSSH接続したときは、Bashコンソールでコマンドを叩いてきましたけど、Cloud9にはGUIのファイルマネージャとテキストエディタがついています。「そうか、これはGNOME,KDEに続く、新しいLinuxのデスクトップ環境なんだ!」と思ったら、自分の中で腑に落ちました。
普通のAmazon Linuxなら、フツーにElastic IPをアサインできるんじゃね?
私が調べた時のシンガポールリージョンでのt2.microインスタンスの料金は、$0.0146/h
でした。月720時間とすると$10.51
です。
Elastic IPの料金は$0.005/h
で月$3.6
です。
Cloud9には、コストを節約するための設定がついていて、私も構築するときに、「30分経ったらEC2インスタンスを停止する」を選んでいます。Elastic IPをアサインしてしまったら、停止しているときもコストがかかるようになります。動作中のコストはかかりません。
つまり、$0.00~$10.51
のコスト予想が、$3.6~$10.51
のコスト予想になるということです。一瞬考えた末に、固定IPアドレスを取得してみることにしました。
AWSマネジメントコンソール > EC2 > リージョンをシンガポールに変更
左枠 > ネットワーク&セキュリティ > Elastic IP
右枠 > 新しいアドレスの割り当てボタン > 割り当てボタン
xxx.xxx.xxx.xxxを入手
右枠 > そのIPを選んでから > アクションドロップダウンリスト > アドレスの関連付け
リソースタイプ: インスタンス
インスタンス: {Cloud9がインストールされているインスタンスのID}
プライベートIP: {Cloud9がインストールされているインスタンスのIP}
関連付けボタン
Cloud9に戻って、右上のShareボタンをクリックしたら、Application欄のIPアドレスがxxx.xxx.xxx.xxxになっていました。成功です。
ならば、今後設置するWebサーバーはCloud9からだけSSH接続できるようにすればいいんじゃね?
東京リージョンのセキュリティグループには、このElastic IPからのSSH接続だけを許可するように設定します。
そして、EC2インスタンスに接続するために必要なSSH鍵を、Cloud9に設置します。Cloud9はローカルのファイルをアップロードできます。
例えば、以下のようなコマンドを叩くと、Cloud9からWebサーバーにログインできるようになります。
ssh ec2-user@{webサーバーのIPアドレス} -i ~/.ssh/{アップしたSSH鍵}.pem
私は、もう場所にもPCにも縛られることなく、Cloud9にアクセスすることができれば(すなわち、AWSマネジメントコンソールにログインすることができれば)、Webサーバーを管理することができるようになりました。
Cloud9は開発環境なんでしょ? ソースコードの管理はどうするの?
Cloud9には、認証情報ヘルパーという機能があって、AWSのリソースを使うためのクレデンシャルが自動的に付与されます。AWS CodeCommitならば、以下の作業だけでGitリポジトリとして使えるようになります。
# コミットをするためのいつもの準備
git config --global user.name "{自分の名前}"
git config --global.user.email {自分のメルアド}
# 認証情報ヘルパーを設定する
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true
# リポジトリからクローンする
git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/{リポジトリ名}
CodeCommitは、シンガポールリージョンにも、東京リージョンにも用意されています。近い将来、Cloud9が東京リージョンに来たときのことを考えて、リポジトリは東京リージョンに作りました。
【上級問題】 アカウントをまたいだCodeCommitは使えるの?
プロファイルを切り替えれば、~/.aws/credentials
ファイルに複数のクレデンシャルを設定できることをご存知の方は、このような疑問をお持ちになるでしょう。CodeCommitに限らず、アカウントをまたいだAWSリソースの操作、私もやってみたくなりました。しかし、それをやるとCloud9からめっちゃ怒られます。
「credentialsファイルを勝手にいじったら、認証情報ヘルパー効かなくなるで。どうなっても知らんからな。」 正直、私はブルッときましたね。
Cloud9開発環境はアカウントごとに作成するべきというのが今の結論です。
認証情報ヘルパーというアドバンテージをaws-cli
で味わう
アカウントをまたいだリソースの操作はすべきではありませんが、リージョンをまたいだリソースの操作はなんの問題もありません。以下のようなBashスクリプトを書くと、東京リージョンでEC2インスタンスが一発で立ち上がります。(--region
オプションで東京リージョンを指定するところがミソです。)
#!/bin/bash
echo "? input name ?"
read name
echo "First, searching ${name}..."
id=`aws ec2 describe-instances --region ap-northeast-1 \
--filters "Name=tag:Name,Values=${name}" "Name=instance-state-name,Values=running" \
--query "Reservations[0].Instances[0].InstanceId" \
--output text`
if [ "${id}" != "None" ]; then
echo "Error, ${id} is running."
exit 2
else
echo "OK! launching ${name}..."
fi
subnet={あらかじめ用意したサブネットのID}
sg={あらかじめ用意したセキュリティグループのID}
image={あらかじめ選んだAMIのID}
type={t2.nano, t2.small, t2.medium...}
key={あらかじめ用意したSSH鍵の名称}
aws ec2 run-instances --region ap-northeast-1 \
--subnet-id ${subnet} \
--security-group-ids ${sg} \
--image-id ${image} \
--instance-type ${type} \
--key-name ${key} --count 1 \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${name}}]" \
--output table \
--no-dry-run
立ち上がったインスタンスに、Elastic IPを与えるスクリプトはこんな感じです。
#!/bin/bash
echo "? input name ?"
read name
case "${name}" in
"web1" ) ip=xxx.xxx.xxx.xxx;;
...
* ) exit 2;;
esac
echo "First, searching ${name}..."
id=`aws ec2 describe-instances --region ap-northeast-1 \
--filters "Name=tag:Name,Values=${name}" "Name=instance-state-name,Values=running" \
--query "Reservations[0].Instances[0].InstanceId" \
--output text`
if [ "${id}" = "None" ]; then
echo "Error, ${name} is not running."
exit 2
else
echo "OK, assigning ip to ${name}..."
aws ec2 associate-address --region ap-northeast-1 \
--instance-id ${id} --public-ip ${ip} \
--output table
fi
「クレデンシャルの設定抜きで、これができちゃうのってラクだわーっ」て思うのは私だけでしょうか?
そして、AnsibleでWebサーバーの内部構成の設定を行う
Cloud9にAnsibleをインストールできました sudo pip install ansible
詳しい説明は省きますが、以下のようなファイル構成でAnsibleを動かします。
|--- templates\
`--- nginx.conf
|-- ansible.cfg
|-- hosts
|-- setup.yml
|-- ssh_config
nginx.confを除いたファイルの中身を披露します。
[defaults]
inventory = ./hosts
retry_files_enabled = False
host_key_checking = False
command_warnings = False
[ssh_connection]
ssh_args = -F ssh_config
[all]
web1
---
- hosts: all
- become: yes
tasks:
- name: set timezone to Asia/Tokyo
timezone:
name: Asia/Tokyo
- name: update installed packages
yum: name=* state=latest
- name: install new apps
yum: name=nginx state=installed
- name: backup original files
shell: mv /etc/nginx/nginx.conf /etc/nginx/nginx.original
- name: copy new files
template:
src: ./templates/nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "644"
- name: start apps
service: name=nginx state=started enabled=yes
Host web1
User ec2-user
HostName xxx.xxx.xxx.xxx
IdentityFile ~/.ssh/{アップしたSSH鍵}.pem
ansible-playbook setup.yml
と叩くと、webサーバーへのnginxのインストールが終わります。
ソースコードのデプロイにはGitを使う
話が長くなって疲れてしまいました。興味がある方は、この記事を参照してください => 「SSH接続があればGitでデプロイできる」
今回のまとめ
私は、Chromeブラウザと、AWSマネジメントコンソールにログインするためのパスワードだけを持っていれば、東京リージョンにあるWebサーバーを管理できるようになりました。インスタンスの起動から、サーバー内部の設定まで、すべてスクリプト化して、リポジトリに放り込むことができました。もちろんアプリケーションのソースコードも同様です。
正直に言うと、SSH鍵のコピーはさすがにローカルに保存しています。でも、これだっていつでも刷新できます。ついにクラウド中心の開発生活を達成できました。イエーイ。
Cloud9が東京リージョンに来たらどうなる?
Elastic IPのアサインが不要になるので、セキュリティがさらに強固になり、そして設定がラクになると思います。しまうと思います。私は、来た初日にCloud9を東京リージョンに移して、セキュリティグループに取り付けたSSH接続の許可を塞いで
ただ、それほど移管作業は簡単なことでもあります。「まだ東京リージョンに来てないから、Cloud9への移行は待ちだわ」にはならないと思います。現時点では、SSH接続の許可がひとつもないサーバーは管理できないはずですからね。Cloud9を採用すれば、SSH接続の許可はひとつに集約できます。
2018/04/14追記 Cloud9が動いているEC2インスタンスのセキュリティグループは、SSH接続の許可が全開になっています。これはログインに成功したブラウザがSSH接続しているからではないかと考えています。なので、Cloud9が東京リージョンに来ても、SSH接続が全閉になるわけではないです。「セキュリティがさらに強固になり、そして設定がラクになる」という発言は取り消します。
Cloud9が東京リージョンに来た初日の作業としては、Cloud9とWebサーバーを別のセキュリティグループにして、WebサーバーへのSSH接続は、Cloud9のセキュリティグループからのみ許可するように設定することになると思います。
Cloud9採用の副産物
Gitコマンドに強くなりました。まさか私がgit reset
コマンドを使うようになるなんて夢にも思っていませんでした。 ちょっとコードを書いたら、git status
git diff
を叩いている自分。だいぶプログラマーっぽくなりました。
最後にお願いです
- 面白いと思っていただけたら「いいね」をクリックしてください。励みになります。
- Cloud9で実現するクラウド開発環境についてご意見あったら、お気軽にコメントしてください。