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.
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.