こんにちは、アイダです。ノンプログラミングでAWSの運用改善できたら良いですよね~。今回は、サーバーに直接ログインしなくても、いろいろできるAWS System Managerを駆使して運用改善を実現したKさんからの投稿です。日々の運用課題を解決したドキュメント例も惜しみなく公開しています。ではKさんお願いします。
課題
Kです。先日、運用業務効率化のために作成した、AWS System Manager(SSM)ドキュメントについてお話ししたいと思います。
(AWS System Managerアイコン)
私の所属部署で開発・運用を担当しているシステムでは、頻繁にEC2インスタンスの停止/起動/インスタンスタイプ変更が必要です。
Auto Scaling を利用してサクッと運用できれば良いのですが、
課題1:停止/起動/インスタンスタイプ変更と同時に、停止/起動/インスタンスタイプ変更とは関係ないサーバー上のDBを更新する必要がある。
課題2:停止/起動/インスタンスタイプ変更は、不定期で実行する必要がある。
上記のような問題があり、すべて手作業で行ってきました。
手作業でも難しくはありませんし、作業時間も数分ですが、「この運用を忘れる/失敗すると、公開処理が失敗して顧客影響が出てしまう・・・」という心理的な負荷は結構なものです。
特にインスタンスタイプ変更は数10台分を手作業で行う必要があり、面倒でした。
そんなのCLIやLamdaでサクッと実装してあげればいいやん!という方は、この記事は読み飛ばしてください。
そんなのヤダよ、もっとお手軽にノンプログラミングで実現したいよ、という方、SSMでオリジナルのドキュメントを作成すればOK!!というのが、今回のお話です。
何をしたか 課題1
さて本題です。
AWS System Manager(SSM)についての説明は、ネット上に豊富に転がっているので割愛します。
サーバーに直接ログインしなくても、いろいろできますよ、てやつですね。
ご存じの方も多いと思いますが、AWSのマネジメントコンソール上でGUIベースで操作できることは、すべてCLIやAPI経由でも実行可能です。
これらのAPIの、実行時のパラメータや組み合わせ、実行順、処理の分岐などを定義しているのが、SSMドキュメントです。
既定のドキュメントが数多く用意されていて、これらを利用すれば、任意のインスタンスにCloudWatchのアラームをセットしてあげたり、必要なパッケージをインストールしてあげたりすることが可能です。
今回のケースは既定のドキュメントではこと足りなかったので、オリジナルのドキュメントを作成しました。
作成したドキュメントの一例を紹介します。
description: Enable agg servers and start pnl servers. schemaVersion: '0.3' assumeRole: '{{ AutomationAssumeRole }}' ## ここで実行時のパラメータを定義 parameters: InstanceIdA: type: StringList description: (Required) InstanceId of DB server. InstanceIdB: type: StringList description: (Required) InstanceIds of aggregate servers. SQLCommand: type: String description: (Required) Update query executed on DB sever. AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. default: '' ## ここで処理ステップを定義 mainSteps: ## 処理サーバー群を起動 - name: startInstance action: 'aws:changeInstanceState' inputs: InstanceIds: '{{ InstanceIdB }}' DesiredState: running onFailure: Abort ## DB更新 - name: enableAggServers action: 'aws:runCommand' inputs: DocumentName: AWS-RunShellScript InstanceIds: '{{ InstanceIdA }}' Parameters: commands: '{{ SQLCommand }}' timeoutSeconds: 60
ドキュメントの書き方や実行方法については、以下の記事が詳しいです。
ので、またまた割愛します。(手抜き・・・じゃないですよ笑)
これで、課題の1「停止/起動/インスタンスタイプ変更と同時に、停止/起動/インスタンスタイプ変更とは関係ないサーバー上のDBを更新する必要がある」を解決できました。
数10台のインスタンスタイプ変更が面倒、という課題も、同様にドキュメントを作成して解決しました。
SSM既定のドキュメントに「AWS-ResizeInstance」というものがあり、これを利用すれば”ほとんどの場合”、複数台のインスタンスタイプ変更が一括実行できます。
が、このドキュメントには落とし穴があり・・・
「AWS-ResizeInstance」の処理ステップは以下の通りです。
- 対象となるインスタンスのインスタンスタイプをチェックし、入力パラメータに設定されてたインスタンスタイプと一致するかを判定する。一致しない場合、2へ進む。
- 対象となるインスタンスを停止する。
- 対象となるインスタンスのタイプ変更を行う。
- 対象となるインスタンスを起動する。
これのどこがダメかというと、EBS最適化オプションの指定がない(=インスタンスタイプ変更前のオプションを引き継いでいる)という点。
EBS最適化オプション、皆さんご存じですよね。
そう、t2ファミリーでは利用できないアイツです。
つまり、t2ファミリー以外からt2ファミリーへインスタンスタイプ変更を行う場合、「AWS-ResizeInstance」を利用すると、「EBS最適化オプション=Trueのt2インスタンス」を起動しようとして、失敗してしまいます。
この問題を解決するために、上記処理ステップの3と4の間に、EBS最適化オプションを設定するステップを挟み込んだドキュメントを作成しました。 (我々のチームでは日頃からt2ファミリーが大活躍しているので、避けて通れなかった・・・)
サンプルとしてドキュメントの一部を抜粋したものを載せます。
parameters: isEbsOptimized: type: Boolean ## 中略 ## mainSteps: - name: assertInstanceType action: 'aws:assertAwsResourceProperty' ## 中略 ## - name: configureEbs action: 'aws:executeAwsApi' inputs: Service: EC2 Api: ModifyInstanceAttribute InstanceId: '{{InstanceId}}' EbsOptimized: Value: '{{ isEbsOptimized }}'
何をしたか 課題2
課題の2「停止/起動/インスタンスタイプ変更は、不定期で実行する必要がある」については、
同じくSSMのメンテナンスウィンドウを使って解決しました。
実行するタスク、実行対象のインスタンスを登録し、Cronなどの形式でスケジューリング実行できる機能です。
詳しくはこちら↓(だから、手抜きじゃ・・・ないですってば笑)
本来はカレンダー形式で実行タイミングを指定できると良いなと思っていたのですが、そんなことは出来ないらしく断念・・・
スケジューリング実行するにはCloudWatchルールでも実現可能ですが、メンテナンスウィンドウの方が、
1.タスクの定義がしやすい(単に設定画面のUIの問題) 1.実行対象のインスタンスをタグで指定できる(=実行対象を変更する時はタグの変更のみでOK)
と考え、メンテナンスウィンドウを採用しました。
最後に
いかがでしたでしょうか、SSM。
使いこなすことができれば、かなりの業務効率化につながるのではないかと思います。
最後までお読みいただき、ありがとうございました。