Capistranoで新規作成したEC2インスタンスの初期設定

本項では、Capistranoで新規作成したEC2インスタンスへSSHで初回ログインした際の、保守用ユーザの作成、初期ユーザに対してのパスワード設定、サーバのホスト名設定など、いわゆるサーバ環境の初期設定を行うタスクを作ってみます。

その前に、ホスト名のつけ方としての色々と試してみての所感なのですが、初回SSHログイン後にそれぞれのインスタンスに対してHOSTS設定する際にEC2側にタグ付けてしていってもできるのですが、まずインスタンス作成する時にあらかじめホスト名の元となるタグを付けておいて、各インスタンスログイン後はそのタグを参照してHOST名を設定する方がスマートだと思いました。特に複数インスタンスを同時に立てる時などにホスト名に連番を振りたいとかいう時は、カウンター変数を使って回しているec2.instances.create()時にそのカウンターの数値を転用できるので簡単でした。ということで、インスタンス作成時にタグを追加する方法ですが、

── と、ec2.instances.create()の後でタグを付けてやればOKです1
今回はこのNameタグの値をその後のタスクでインスタンスのホスト名として利用します。

いきなり横道に逸れましたが、本題に戻ります。
初回SSH時のタスクとして、前回作成したinitタスクを使います。流れとしては、デプロイサーバ側で新たに作成するユーザ用のキーペアを作成しておいて、デフォルトユーザにてSSHログイン後、まず保守用の新規ユーザアカウントを作成ます。その後、そのユーザに公開鍵認証によるSSH設定を行い、デフォルトユーザにはパスワードを設定してsudo権限を剥奪、ホスト名を設定して一旦ログアウトしています。
まず、タスク設定前に各種パラメータを定義します。

そして、初期設定用のタスクinitです。

いやはや、CapistranoやRuby、DSLの知識が乏しくて結構難航しました。結構ハマったのが、sudo系のコマンドを複数連携させるような使い方(リダイレクトとパイプ)をする時です。例えばワンライナーでパイプでチェーンさせるコマンドの場合、例えばexecute :sudo, "mkdir ~/new_dir | chmod a+w ~/new_dir"のような繋げ方をすると、チェーンした後続のchmodがsudo権限にならず、mkdirしか実行されなかったので、execute :sudo, "mkdir ~/new_dir | sudo chmod a+w ~/new_dirのように繋げたら上手くいきました。また、>とか>>のリダイレクトを使って標準出力をファイルに追記するような処理はエラーになって動かず、標準出力を拾えるchpasswdteeようなコマンドでパイプでチェーンさせる必要がありました。
あと、今回checkinitのタスクにて、「AWS SDK for Ruby」でAPIを使っているところのレスポンスについてキャッシュがあればそれを利用するようにAWS.memoizeメソッドでメモ化してみました(詳しくはこちらのサイト)。このメモ化を行うことで、checkタスクでAPIレスポンスがキャッシュされるので、後続のinitタスクのパフォーマンスが抜群に早くなりました。

では、タスクを実行してみます。

デプロイ成功です。
確認のため、コマンドラインから新しく作られた保守用ユーザでSSHログインしてみます。

無事、ログインできました。
さらに、保守用ユーザはパスワードなしでsudoでき、一方、デフォルトユーザのec2-userはsudo権限が剥奪されています。期待通りのデプロイができています。

ただ、このデプロイ設定にはちょっと問題があって、インスタンスラウンチ用のタスク後のインスタンス状態(Instance State)が:runningになって起動済みでも、ステータス確認(Status Checks)が:initializing状態だと、初回SSHが出来ずにinitタスクが途中で停止してしまいます。現状のcheckタスクではInstance Stateが:runningかどうかしか見ていないための問題ですね。

長くなってきたので、今回はここまでとします。次回は、Status Checksを判定するcheckタスクの改修を行ってみるのと、今回のinitタスクのafter処理として、新たに作成された保守用ユーザのSSH設定をCapistranoの設定ファイルに書き出す処理、そしてようやくパッケージアップデートを行う本来のデプロイ処理の導入までを作ってみようかと。

参考サイト

  1. NameタグはAWSマネージメントコンソールのインスタンス一覧の名前としても使われるので、このタグを付けておくと、作成したインスタンスが判別し易くなるためオススメします。 

おすすめ記事