簡単すぎる!EC2 インスタンスの中身をほぼ全自動で更新しよう
めんどくさいことは嫌いです、那須です。
業務でも個人検証でもなんでもいいんですが、普段使ってる EC2 インスタンスのゴールデンイメージの中身(ドライバとかツール類)だけ更新してまた AMI 化するタスクってあったりしませんか? 私も個人検証環境でそんなことを手作業でしてたんですが、ふと「あれ?これってSSMでできるんちゃうかったっけ?」って思い出したので、ドキュメントを確認してみるとやっぱりありました。
個人環境だと普段は Linux 環境しか触らないので↑のような作業もそんなに苦じゃないですが、Windows となるとちょっとしんどいですね。 なので、Windows 環境で SSM の自動化を試してみました。
SSM 自動化がない時
Windows だと、ドライバとか更新して Windows Update 実行して再起動してまた Windows Update 確認して再起動して動作確認して、、、
やってられん!
時間もかかるしちょいちょい画面見ておかないといけないしで、わりと手も時間もとられてつらいですよね。
SSM 自動化がある時
SSM 自動化を使うと、
- 簡単すぎる
- 作業用インスタンスの作成削除も忘れずに勝手にやってくれる
- 実行中は安心して他のタスクができる
- 実行完了後の動作確認だけに意識を集中できる
- 実行ログも残せる
- Windows Update だと適用した KB 番号もログで確認できる
とこんな感じでいいことがたくさんあります。
SSM 自動化の流れを見てみましょう
AWS管理コンソールの EC2 の画面に「自動化」があるので、そこに行ってとりあえずボタンを押します。
AWS-UpdateWindowsAmi という名前のドキュメントがあるのでそれを選びます。他にもたくさんのドキュメントがあるので、いろいろ眺めてみるといいですよ。こんなこともできるの!?って発見がきっとあります。
パラメータを入れていきます。更新する AMI ID とか実行ロールとか。最後に「自動化を実行」ボタンを押しましょう。
自動化が始まると、コンソールで状況を見れるようになります。この画面は、実行直後なのでまだ作業用インスタンスを起動している最中ですね。
EC2 インスタンスのコンソールでは、作業用インスタンスが起動しているのが見えました。
作業用インスタンスのセキュリティグループには、default がつけられていました。確かにいろいろ更新するだけでインバウンド通信は発生しないので、これで作業中に外から何かされる心配もないですね。
小一時間ほど経つと自動化タスクが完了しました。今回は無事に全タスクでエラーなく完了したようです。
タスクのログを見てみましょう。EC2 Config の更新については、すでに最新バージョンだったのでスキップされているようです。
Windows Update は 3 件更新対象の KB が見つかったので、ダウンロードして適用されています。何が更新されたのかも一目瞭然ですね。
作業用の EC2 インスタンスも削除されていました。更新して AMI 作成して満足して EC2 インスタンスの削除を忘れる、なんてこともこれでなくなります。
自動化タスクでドライバやツール類を更新して作成された AMI がちゃんと見えます(当たり前か…
この AMI から EC2 インスタンスを起動して動作確認も問題ないことまで確認済みです。
楽をするために時間を使おう
今回は Windows Update や各種ドライバ類を更新する自動化をご紹介しました。 定型作業を自動化しよう!って声はいろんなところで見聞きしていると思いますが、その自動化手段も別に自分たちで一から作る必要はないですね。 既にあるものはガンガン使って無い部分だけを自分たちで作るようにすれば、それをメンテナンスする時間も最小化できるでしょうし、最終的には同じタスクを完遂させるのも自動化する前に比べて楽になっていると思いますよ。 そして楽になれば、他のやらないといけないことに時間を使えたり、以前からやりたかったことに時間を使えるようになります。
すべてがうまくいくかどうかはわかりませんが、SSM や他の仕組みを使っていろいろ試してもっと楽になりたいなーと思いました。
Secrets Manager を使ってパスワードを入力せずに RDP してみた
パスワード管理めんどくさいです、那須です。
PrivateLink 経由で Secrets Manager が使えるようになったと AWS から発表がありました。 AWS Secrets Manager Now Supports AWS PrivateLink
これ読んで、そういえば Secrets Manager 全くやってなかったな。。。と思ったのでひとまずやってみました。 ただシークレット情報を取り出すだけだと他のブログでたくさん書かれているので、Windows Server に RDP するためのパスワードをシークレット情報として登録して、それを PowerShell から取り出して RDP できるかどうかをテストしてみます。
ドキュメント
ドキュメントは日本語でちゃんとあります。これまでの教訓を生かしながらも時間があまりないので、さっと読みます。 docs.aws.amazon.com
まずはシークレットの作成から
AWS管理コンソールで Secrets Manager の画面に行き、シークレット作成画面で他の種類のシークレットを選びます。その下にあるシークレットキー/値にそれぞれ入力します。今回は RDP 用のパスワードだけをいれます。
KMS の暗号化キーを選択して「次へ」を押します。CMK を使うこともできるようですが、今回はデフォルトのものを使います。
シークレット名と説明を書いて「次へ」を押します。
パスワード等の自動ローテーションができるようです。RDS とかだとすでにサポートされてるってドキュメントに書いてあった気がします。今回は無効にしたまま進みます。
確認画面で内容を確認します。
確認画面の下の方にサンプルコードがあります。いちいち自分で考えてコードを書かなくても済みますね。これは嬉しい(Powershellはないけど。。。
ここまで終われば、こんな感じでシークレットが作成されていると思います。
シークレット情報をとってくる PowerShell コマンド
まずはドキュメントでさっと確認します。CLI や SDK はこちらのドキュメントを。 docs.aws.amazon.com
PowerShell の場合はこちら。 docs.aws.amazon.com
まずは、シークレット情報をざっととってくるコマンドを試してみます。ARN とか 値 が返ってきますね。
> Get-SECSecretValue -SecretId test_pass -Region ap-northeast-1 ARN : arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:test_pass-XXXXXX CreatedDate : 2018/07/13 5:56:14 Name : test_pass SecretBinary : SecretString : {"password":"naisyonopasuwa-do"} VersionId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx VersionStages : {AWSCURRENT}
内容が取れたのは嬉しいのですが不要な情報まで取れてるので、このままではスクリプトの中で使えません。 パスワードだけを取り出すために、結果を JSON に変換してその値だけを取り出すコマンドがこちらです。
> ((Get-SECSecretValue -SecretId test_pass -Region ap-northeast-1).SecretString|ConvertFrom-Json).password naisyonopasuwa-do
これでパスワードをテキストとして取り出すことができました。
いよいよ RDP を PowerShell から実行
↓のスクリプトを testrdp.ps1 ファイルにします。
echo "Connecting to xx.xx.xx.xx" $Server = "xx.xx.xx.xx" $User="Administrator" $Password = ((Get-SECSecretValue -SecretId test_pass -Region ap-northeast-1).SecretString|ConvertFrom-Json).password cmdkey /generic:TERMSRV/$Server /user:$User /pass:$Password mstsc /v:$Server
そして実行!
> .\testrdp.ps1 Connecting to xx.xx.xx.xx CMDKEY: 資格情報を正しく追加しました。
↑のような結果が返ってきた直後に、下のような RDP のプロンプトが出てきます。 ここまでくればいつものオペレーションですね。
はい!Windows Server にパスワードを入力することなく RDP 接続できました!
もうちょっと詳細調べて使いたい
Secrets Manager を使うと、シークレット名だけわかればいいので、
- パスワードを覚えなくてもい
- パスワードを関係者に周知しなくてもいい
- パスワードをローカルマシンに保存しなくてもいい
- パスワードを更新したとしても Secrets Manager で更新すればユーザはその変更を意識する必要がない
- パスワードと一緒に渡したい情報も書いておいて一緒に取れるようにできる
といいことばかりなので、皆さんもぜひ使ってみてください! 今回はパスワードを例にしてやってみましたが、ユーザ名でもいいしサーバ名でもいいし、なんにでも応用が利くと思います。
まあ今時は SSO とか MFA とかがあるのでもしかしたら「これを待ってた!」って人は少ないのかもしれませんが、コードを書いてる人だとクレデンシャル情報をどこに置くかは結構頭を悩ませる問題だったりするので、知っておいて損はないと思いますよ。