CapistranoでAWS EC2インスタンスをデプロイする時の注意点

前回のデプロイ設定ファイルで新たに作成されたEC2インスタンスには、キーペアセキュリティグループなどが設定されていなかったため、そのままでは作成したインスタンスにSSHでアクセスできませんでした…1orz

その後、色々とデプロイ設定を修正して、作成したEC2インスタンスにSSHでログインするところまで出来たので、その経緯を備忘録として書いてみた次第。
まぁ、CapistranoでAWSのEC2インスタンスを作成する際…というより、「AWS SDK for Ruby」でEC2インスタンスを作成する時の注意点…に近いのかもしれない。

まず、前回のconfig/deploy.rbからインスタンスラウンチのタスク部分を見てみる。

作成するインスタンスに対して、AvailabilityZoneとSubnetの設定しかしていないので、そりゃあアクセス不能になります。最低限、セキュリティグループを設定して、外部からのアクセス経路を確保して、キーペアを設定して認証ユーザがログイン可能にしてあげる必要はあります。あとは、PublicIP(PublicDNS)を自動で割り振られるようにして、インターネットからのアクセスも出来るようにしておくあたりまでが、最小設定となるかと。

では早速、修正してみます。
まずは、必要な設定値を変数として追加します。

キーペアやセキュリティグループはAWSコンソールで事前に作っておく必要があります。手っ取り早いのは、デプロイ環境としてCapistranoが稼動しているインスタンスのキーペアとセキュリティグループをそのまま利用するのが良いでしょう。カーネルIDは必要に応じて設定します。別になくても問題は出ないので。
そして、ec2クラスのメソッド部は下記のように変更します。

新たに追加したメソッド・オプションは下記の通りです。

  • :block_device_mappings EBS(ELASTIC BLOCK STORE)の設定です。インスタンス固定のストレージ容量に追加が必要であれば、追記します。この例では、50GBのストレージボリュームを追加しています2
  • :monitoring_enabled インスタンス起動後にCloudWatchのモニタリングを開始する場合はTRUEにします。
  • :key_name … 必須設定値です。キーペア名を指定します3。ここでは先に定義した変数を呼んでいます。
  • :security_group_ids 必須設定値です。すでに定義済みのセキュリティグループIDを配列形式で記述します4。ここでは先に定義した変数を呼んでいます。
  • :kernel_id カーネルIDを使用する場合に指定します。同じカーネルIDでHMV対応AMIから複数インスタンスを作成しようとするとエラーになるので、その場合は指定しない。
  • :disable_api_termination EC2 APIを利用してインスタンスを終了させることを可能にする場合はTRUEにします。
  • :associate_public_ip_address 重要設定値です。作成されたインスタンスにPublicIPアドレスを自動割り当てさせたい場合はTRUEにします5

それでは、修正したデプロイ設定で、インスタンスラウンチタスクを実行してみます。

※ ちなみに、Capistranoのタスクのデバッグを行いたい場合は、cap test launch debugとかcap test launch --traceとオプションを付けてタスクを実行すると詳しく処理をトレースしてくれるので覚えておくと便利です。

AWSのマネージメントコンソールで確認してみます。
スクリーンショット1

スクリーンショット2

キーペアもセキュリティグループ、PublicIPまで期待通りのEC2インスタンスがラウンチされました。
では、コンソールからSSHが出来ることを確認してみます。

入れました。ただし、今回の例では、すでにSSHアクセスができる「default-user」というユーザを事前に作成してあったAMIからインスタンスを作成したので、すんなりログインできましたが、前回の例のようにAWS公式のAMIからインスタンスを作成した場合は、もう一手間かかります。では、前回同様に「Amazon Linux AMI 2014.03.2 (HVM)」の公式AMIを利用して、「t2.micro」にインスタンスを作成するタスクに修正してみます。HVM対応AMIからインスタンスラウンチする際にエラーになる、EBS設定とカーネルIDの指定を取り払います。

では、実行します。

AWSマネージメントコンソールで作成されたインスタンスIDからPrivertIPを確認したら、コンソールからAmazon Linux系AMIのデフォルトユーザ「ec2-user」でSSHしてみます。

当たり前ですが、接続は出来るものの、公開鍵認証でこけてアクセス出来ませんでした。プライベートキーをssh -iのオプションで添付して認証しないと接続はできません。つまり、作成したインスタンスに対してCapistranoで次のタスクを実行するためには、Capistranoの稼動しているデプロイサーバ側に事前にインスタンス作成に使うプライベートキーを準備しておく必要があります。そして、新規インスタンスへの初回のSSHではそのプライベートキーを使ってログインを行うという流れになるはずです。
ひとまず本項はここまでとします。次回は、インスタンスラウンチ直後のタスクとして、Capistrano経由で新インスタンスにSSHする手順をまとめてみます。

参考サイト


  1. SDKのドキュメントに注意が書いてあった(以下原文”:key_name (String) — The name of the key pair to use. Note: Launching public images without a key pair ID will leave them inaccessible.”) 
  2. EBSボリュームを利用する場合、HVM対応AMIは利用できなくなります。そのため、作成するインスタンスタイプはHMV専用の「t2.micro」ではなく「t1.micro」等へ変更する必要があります。 
  3. 挙動を試してはいませんが、キーペアをインポートすることもできるようです。その場合の記述は :key_pair => ec2.key_pairs.import(fetch(:key_pair_name), File.read('~/.ssh/identity.pub')), のようになるのでしょうか?(未検証) 
  4. セキュリティグループを指定しないと、デフォルトのグループのみが設定され、同じVPCネットワークからしかアクセスできなくなります。 
  5. デフォルト設定値がFALSEなので、この設定を入れないとPublicDNSも有効になりません。 

おすすめ記事