経緯
EventBridgeをキックしてLambdaでEC2を停止するスケジューリングを立てようとしたところ、Lambda実行で権限のないエラーが発生したので、調査した結果を記事にしてみようと思った。
構成
Lambdaのコード
言語は「Python3.9」です。
import boto3
region = 'ap-northeast-1'
instances = ['i-0cfa865823946e45e']
def lambda_handler(event, context):
ec2 = boto3.client('ec2', region_name=region)
ec2.stop_instances(InstanceIds=instances)
Lambda実行後のエラーメッセージ
StopInstancesを実行するための権限がありません。といったところでしょうか。
Lambdaの権限ロールを確認してみます。
[ERROR] ClientError: An error occurred (UnauthorizedOperation) when calling the StopInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: zSo5Msmd-JQRo8ygxWtAmj9ZRU78GGqhzYCssr7BAb4WksmLG1uYqGnZFwkDluF00PB58j1hl9aThYkwLJn_6sFw3YhHS57HwAIyPXm_6vuMI7KHwiwPEB8pPpvLjwP0sW8lDItpzRGQf7_KZTHEurtVAOj5GXRHkk8eKexR6JgLSDxTrYTfqdBc9LJd11pJF31IgrLYYbyglhmoolKOZ1xgHQQMdkg7pJXP1pKLPIBNyyCGQxXovyQkPWhgOf8Ex4cxPNzKuDjKU0qbHkqY8iUWNozgWP_nzFyWQqV0DSMe8sg_931OZYHmX0uaV-r4sX93KtbqXkb3P_C8J_jg9Qt-01DwNgaACzG_QDubyjUJikLAlreRBGmtdTFGm0a9AhrrecGM5OnJYLBnc-7IPzagKe-fZFRZOz6V3AekXxQhMK_mlUO-9tPbAngWSE1X5fk1Y_Jc8YF6HOnquJ2nIytNMmI54k9RvpG9cRl14oc4EckmTWPkGM5VjyVD1qDZjIhu7DJ_mOjg5CqG28Sue9VH9RL31eCqv8U7hPhIvah1c0zP8W_vdJYQMcze1RyENQQmqXJtp5kX9Etl1urBHnNtXILgZmLFmANUphlUuo4ZBuG21FVL1cT_rex7LoAoQOk_60nBfgXP4GZJ5NctBvVg95lsbxluvXgHlXdgW_JrwXTPv8MMHThx45Y2wtltYjPEBxGqT6kH
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 9, in lambda_handler
ec2.stop_instances(InstanceIds=instances)
File "/var/runtime/botocore/client.py", line 386, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 705, in _make_api_call
raise error_class(parsed_response, operation_name)
Lambdaの実行ロール権限確認
どうやら、Lambda関数作成時のデフォルトロールが適用されていたようです。
正しいのは、事前に作った「Lambda_execution_role」というものです。
このロールには、"Logsの権限"・"EC2の停止権限"が入っています。
デフォルトで作成されるとロールにはEC2の実行権限がついていないのでエラーが権限不足のエラーが発生したと思います。