AWS 上の EC2 インスタンスから AWS コマンドライン インタフェース (AWS CLI) を使用してコマンドを実行し、AWS の管理を行いたいことがあります。
例えば、cron と組み合わせてボリュームのバックアップを取得したり、利用しない時間帯に EC2 インスタンスを停止することで、Spot インスタンスの料金をさらに抑制したい場合などです。
こうした AWS CLI の実行に必要な権限を EC2 インスタンスに割り当てる方法について、まとめました。
以前の手法
EC2 インスタンスから AWS CLI を使う場合、以前であれば AWS コンソールの IAM 画面からアクセスキーを発行した後、EC2 インスタンスのホームディレクトリに .aws/credentials ファイルを作成し、ここにアクセス キー ID とシークレットを保存したりしていました。
$ cat .aws/credentials
[default]
aws_access_key_id = AKIABCDEFGHIJKLMNOPQ
aws_secret_access_key = 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
この手法は今でも有効で、利用できますが、認証情報をファイルに直接保持するというのはセキュリティ上リスクのある方法です。
また、管理上も煩雑であり、メリットが少ない方法だといえます。
現在の手法
現在であれば、コマンドの実行に必要な権限を持つ IAM ロールを作成して、作成した IAM ロールを EC2 インスタンスに割り当てるという方法を選択すべきです。こうすると、EC2 側には特別な情報を持たせなくとも、必要な AWS CLI コマンドを実行できます。
- コマンドの実行に必要な権限を持つ IAM ロールを作成する
- コマンドを実行したい EC2 インスタンスに IAM ロールを割り当てる
- EC2 インスタンスからコマンドを実行する
このような流れになります。
設定前の動作
ここでは、実行したい AWS CLI コマンドが下記のとおりだとします。
aws ec2 stop-instances --region ap-northeast-1 --instance-ids i-01a23b45c67d89e01
このコマンドでは、アジアパシフィック(東京)リージョンに存在する、インスタンス ID が i-01a23b45c67d89e01 である別の EC2 インスタンスを停止しようとしています。
何も構成していない状態で、適当な EC2 インスタンスから上記のコマンドを実行すると、以下のようにエラーが発生します。
$ aws ec2 stop-instances --region ap-northeast-1 --instance-ids i-01a23b45c67d89e01
Unable to locate credentials. You can configure credentials by running "aws configure".
AWS 上で起動されている EC2 だからといって、任意の AWS CLI コマンドを自由に実行できるわけではないため、このエラーが発生するのは当然です。エラーメッセージの通り、認証情報が存在しない限り AWS CLI コマンドを実行することはできません。
ここでエラーメッセージは「aws configure コマンドを使って認証情報を構成せよ」と告げています。しかし、今回はこのメッセージに従うのではなく、IAM ロールを作成して EC2 インスタンスに割り当てる方法で進めていきます。
IAM ロールの作成
AWS コンソールから Identity and Access Management (IAM) 画面を開き、ロールの一覧で [ロールを作成] をクリックして、IAM ロールの作成を開始します。
[信頼されたエンティティタイプ] はデフォルトの [AWS のサービス] のまま、[サービスまたはユースケース] のリストから [EC2] を選択して [次へ] をクリックします。
続いて許可ポリシーを選びます。
実行したい AWS CLI コマンドが EC2 インスタンスを停止する ec2 stop-instances なので、EC2 インスタンスに対してアクセス許可するため [AmazonEC2FullAccess] を検索して選択します。違うコマンドを実行する場合は、実行したいコマンドに応じて、ここで別のポリシーを選んだり、複数のポリシーを組み合わせて選ぶことができます。
ロール名を自由に入力します。ここでは、"aws-ec2-full-access-role" としました。
ページをスクロールして設定内容を確認した後、一番下の [ロールを作成] をクリックすると、設定した内容で IAM ロールが作成されます。
EC2 インスタンスへの IAM ロールの割り当て
続いて、作成した IAM ロールを EC2 インスタンスに割り当てます。
AWS コンソールから EC2 画面を開き、インスタンスの一覧に移動します。AWS CLI コマンドを実行したい EC2 インスタンスを選択して、右クリックまたは画面右上の [アクション] メニューから [セキュリティ] - [IAM ロールを変更] を選びます。
作成した IAM ロール(ここでは aws-ec2-full-access-role)をリストから選び、[IAM ロールの更新] をクリックすると、EC2 インスタンスへのロールの割り当てが完了します。
設定後の動作
IAM ロールの作成と EC2 インスタンスへの割り当てが完了したので、先ほどエラーになっていたコマンドをもう一度実行してみます。
$ aws ec2 stop-instances --region ap-northeast-1 --instance-ids i-01a23b45c67d89e01
{
"StoppingInstances": [
{
"InstanceId": "i-01a23b45c67d89e01",
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
今度は AWS CLI コマンドが正常に実行されたことが分かります。--instance-ids パラメーターで指定した ID の EC2 インスタンスが、running(実行中)状態から stopping(停止中)状態に変わりました。
EC2 インスタンスの状態は、AWS コンソール上でも確認できます。しばらくすると、対象インスタンスの状態が stopped(停止済み)に変わります。
まとめ
EC2 インスタンス上から AWS CLI コマンドを実行するには、コマンドの実行に必要な権限を持つ認証情報が必要です。
以前と異なり現在では、EC2 インスタンス内の .aws/credentials ファイルに認証情報を直接埋め込む代わりに、適切な IAM ロールを作成して EC2 インスタンスに割り当てる方法を利用できます。
この方法では、構成に必要な手順をすべて AWS コンソールから行うことができます。EC2 インスタンス側に情報を持たせる必要のない、スマートな構成方法が提供されているといえます。