英文:
Not Authorised Error: AWS lambda ec2.run_instances from launch template with boto3
问题
我试图从我的Lambda运行AWS EC2实例。从本地计算机创建实例时,我尝试过以下操作:
import boto3
launchTemplateId = 'lt-000'
ec2 = boto3.client('ec2', region_name='ap-xx-1')
template_specifics = {
'LaunchTemplateId': launchTemplateId
}
resp = ec2.run_instances(
MaxCount=1,
MinCount=1,
LaunchTemplate=template_specifics,
ImageId='ami-00000'
)
print(resp['ResponseMetadata']['HTTPStatusCode'])
而我在Lambda上尝试了以下操作:
def create_instance(lt_id, img_id, region):
"""从启动模板创建实例。"""
ec2 = boto3.client('ec2', region_name=region)
resp = ec2.run_instances(
MaxCount=1,
MinCount=1,
LaunchTemplate={
'LaunchTemplateId': lt_id
},
ImageId=img_id
)
return(resp['ResponseMetadata']['HTTPStatusCode'])
使用IAM策略如下:
....
{
"Effect": "Allow",
"Action": [
"iam:PassRole",
],
"Resource": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${aws_iam_role.xx_role.name}"
},
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": "arn:aws:ec2:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"
}
......
请注意,我甚至尝试了通配符*,甚至根据这个评论建议添加了PassRole
,但每次都显示以下错误:
ClientError: An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. ......
Traceback (most recent call last):
File "/var/task/xxxx.py", line 153, in xxxx_handler
instance_create_resp = create_instance(lt_id, img_id, region)
File "/var/task/xxxx.py", line 79, in create_instance
resp = ec2.run_instances(
File "/var/runtime/botocore/client.py", line 391, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 719, in _make_api_call
raise error_class(parsed_response, operation_name)
我做错了什么?有任何想法将非常有帮助。
更新
我能够追踪到问题,它是由于“tags”和“InstanceProfile”引起的此错误。
TagSpecifications=[{
'ResourceType': 'instance',
'Tags': [
{ 'Key': 'Name',
'Value': 'name'
}]
}],
IamInstanceProfile={
'Name': PROFILE
},
这会导致相同的错误,否则它可以正常工作。
英文:
I am trying to run aws ec2 instances from my lambda.
Creating instance from local machine works when I tried this -
import boto3
launchTemplateId = 'lt-000'
ec2 = boto3.client('ec2', region_name='ap-xx-1')
template_specifics = {
'LaunchTemplateId': launchTemplateId
}
resp = ec2.run_instances(
MaxCount=1,
MinCount=1,
LaunchTemplate=template_specifics,
ImageId='ami-00000'
)
print(resp['ResponseMetadata']['HTTPStatusCode'])
And I am trying this on lambda -
def create_instance(lt_id, img_id, region):
""" creates instance from launch template. """
ec2 = boto3.client('ec2', region_name=region)
resp = ec2.run_instances(
MaxCount=1,
MinCount=1,
LaunchTemplate={
'LaunchTemplateId':lt_id
},
ImageId=img_id
)
return(resp['ResponseMetadata']['HTTPStatusCode'])
with IAM policy -
....
{
# "Sid": "PassExecutionRole",
"Effect": "Allow",
"Action": [
"iam:PassRole",
],
"Resource": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${aws_iam_role.xx_role.name}"
},
{
"Effect": "Allow",
"Action": [
"ec2:*"
# "ec2:StartInstances",
# "ec2:RunInstances"
],
# "resource": "*"
"Resource": "arn:aws:ec2:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*"
}
......
Notice I even tried with wildcard * too, even added passRole as a comment suggested but every time it just shows this error -
ClientError: An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. ......
Traceback (most recent call last):
File "/var/task/xxxx.py", line 153, in xxxx_handler
instance_create_resp = create_instance(lt_id, img_id, region)
File "/var/task/xxxx.py", line 79, in create_instance
resp = ec2.run_instances(
File "/var/runtime/botocore/client.py", line 391, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 719, in _make_api_call
raise error_class(parsed_response, operation_name)
What am I doing wrong?
Any ideas will be much helpful.
UPDATE
I was able to track down the problem and it's 'tags' and 'InstanceProfile' which are causing this error.
TagSpecifications=[{
'ResourceType': 'instance',
'Tags': [
{ 'Key': 'Name',
'Value': 'name'
}]
}],
IamInstanceProfile={
'Name': PROFILE
},
This causes the same error, else it works.
答案1
得分: 0
解决方案:
在创建时,Lambda 没有权限来“标记”资源“ec2”。我不得不根据文档建议,将“ec2:CreateTags”添加到策略中,这解决了问题。
{
"Action": [
"ec2:RunInstances"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": "arn:aws:ec2:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*/*",
"Condition": {
"StringEquals": {
"ec2:CreateAction": "RunInstances"
}
}
}
注意:您还需要添加
sts
权限以传递角色。
祝一切顺利。
英文:
Solution:
The lambda did not have permission to Tag
resource ec2
while creating. I had to add "ec2:CreateTags"
to the policy as the doc suggested, and this solved the issue.
{
"Action": [
"ec2:RunInstances"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": "arn:aws:ec2:${var.aws_region}:${data.aws_caller_identity.current.account_id}:*/*",
"Condition": {
"StringEquals": {
"ec2:CreateAction" : "RunInstances"
}
}
}
> Note: You will also need to add sts
permission for passing role.
Best wishes.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论