How to get the current execution role in a lambda? - amazon-web-services

I'm having issues with a lambda that does not seem have the permissions to perform an action and want to get some troubleshooting information.
I can do this to get the current user:
print("Current user: " + boto3.resource('iam').CurrentUser().arn)
Is there a way to get the execution role at runtime? Better yet, is there a way to get the policies that are attached to this role dynamically?
They shouldn't change from when I created the lambda, but I want to verify to be sure.

Check this: list_attached_user_policies
Lists all managed policies that are attached to the specified IAM
user.
An IAM user can also have inline policies embedded with it.
If you want just the inline policies: get_user_policy
Retrieves the specified inline policy document that is embedded in the
specified IAM user.

Do not know, how much relevance this will bring to the OP.
But we can get lambda function configuration at runtime.
lambda_client = boto3.client('lambda')
role_response = (lambda_client.get_function_configuration(
FunctionName = os.environ['AWS_LAMBDA_FUNCTION_NAME'])
)
print(role_response)
role_arn = role_response['Role']
role_response will have role arn.
role_response =>
{'ResponseMetadata': {'RequestId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'GMT', 'content-type': 'application/json', 'content-length': '877', 'connection': 'keep-alive', 'x-amzn-requestid': ''}, 'RetryAttempts': 0}, 'FunctionName': 'lambda_name', 'FunctionArn': 'arn:aws:lambda:<region>:<account_id>:function:lambda_arn', 'Runtime': 'python3.8', 'Role': 'arn:aws:iam::<account_id>:role/<role_name>', 'Handler': 'handlers.handle', 'CodeSize': 30772, 'Description': '', 'Timeout': 30, 'MemorySize': 128, 'LastModified': '', 'CodeSha256': '', 'Version': '$LATEST', 'VpcConfig': {'SubnetIds': [], 'SecurityGroupIds': [], 'VpcId': ''}, 'TracingConfig': {'Mode': 'PassThrough'}, 'RevisionId': '', 'State': 'Active', 'LastUpdateStatus': 'Successful'}

Related

Fetch IAM Username as the output

`We are running an AWS Glue job and we believe the following code snippet should return the AWS UserId from which the job is being triggered.
For ex, the following code was run with the user mmohanty
import boto3 client = boto3.client('sts') response = client.get_caller_identity() print('User ID:', response['UserId'])
The output is being shown as **AROA6CNCYWLF5MGCB5DF4:GlueJobRunnerSession **instead of IAM username.
The entire output of client.get_caller_identity() doesn't have any reference to IAM username.
{'UserId': 'AROA6CNCYWLF5MGCB5DF4:GlueJobRunnerSession', 'Account': '1234567', 'Arn': 'arn:aws:sts::12345678:assumed-role/xxx-GlueRole/GlueJobRunnerSession', 'ResponseMetadata': {'RequestId': 'bb43bd2b-4426-46b5-8457-aaaaaaa92116d', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'bb43bd2b-4426-46b5-8457-aaaaaaa2116d', 'content-type': 'text/xml', 'content-length': '459', 'date': 'Fri, 20 Jan 2023 17:31:27 GMT'}, 'RetryAttempts': 0}}
Please let us know how to get IAM username instead of the cryptic userid.
We are getting cryptic Userid instead of actual IAM username.`

How can I specify routing policy via the boto3 change_resource_record_sets function?

When I create a record in my hosted zone via the AWS Web Console, I can select the Routing Policy as "Simple".
When I try to create the same record programmatically via boto3, I seem to have no option to set a Routing Policy, and it is "Latency" by default.
What am I missing?
r53.change_resource_record_sets(
HostedZoneId=hz_id,
ChangeBatch={
'Changes': [{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': root_domain,
'Type': 'A',
'Region': region,
'AliasTarget': {
'DNSName': f's3-website.{region}.amazonaws.com',
'EvaluateTargetHealth': False,
'HostedZoneId': s3_hz_id,
},
'SetIdentifier': str(uuid.uuid4())
}
}]
}
)
removing region and SetIdentifier works for me here - can't explain it though :)

IAM Permissions Errors When Using boto3 for AWS Comprehend

I'm playing around with the command line to run some sentiment analysis through aws and am running into some IAM issues. When running the "detect_dominant_language" function, I'm hitting NotAuthorizedExceptions despite having the policy in place to allow for all comprehend functions. The policy for the account is:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"comprehend:*",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:GetBucketLocation",
"iam:ListRoles",
"iam:GetRole"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
Any ideas of where I might be going wrong with this? I've triple-checked my access key to make sure that I'm referring to the correct account. When I check the policy, it's there so I'm a little bit at a loss as to the disconnect. S3 seems to be working fine as well.
Steps already taken:
Resetting access key/secret access key.
Creating iam policy which explicitly refers to the needed functionality and attaching it to the "Admin" user.
Calling this method from the CLI (get the same error).
Below, I've included additional information that may be helpful...
Code to check iam policies:
iam = boto3.client('iam',
aws_access_key_id = '*********************',
aws_secret_access_key = '*************************************')
iam.list_attached_user_policies(UserName="Admin")
Output:
{'AttachedPolicies': [{'PolicyName': 'ComprehendFullAccess',
'PolicyArn': 'arn:aws:iam::aws:policy/ComprehendFullAccess'},
{'PolicyName': 'AdministratorAccess',
'PolicyArn': 'arn:aws:iam::aws:policy/AdministratorAccess'},
{'PolicyName': 'Comprehend-Limitied',
'PolicyArn': 'arn:aws:iam::401311205158:policy/Comprehend-Limitied'}],
'IsTruncated': False,
'ResponseMetadata': {'RequestId': '9094d8ff-1730-44b8-af0f-9222a63b32e9',
'HTTPStatusCode': 200,
'HTTPHeaders': {'x-amzn-requestid': '9094d8ff-1730-44b8-af0f-9222a63b32e9',
'content-type': 'text/xml',
'content-length': '871',
'date': 'Thu, 20 Jan 2022 21:48:11 GMT'},
'RetryAttempts': 0}}
Code to trigger error:
comprehend = boto3.client('comprehend',
aws_access_key_id = '*********************',
aws_secret_access_key = '********************************')
test_language_string = "This is a test string. I'm hoping that AWS Comprehend can interprete this as english..."
comprehend.detect_dominant_language(Text=test_language_string)
Output:
ClientError: An error occurred (NotAuthorizedException) when calling the DetectDominantLanguage operation: Your account is not authorized to make this call.
I encountered the same error and I end up creating a new user group and a user for that particular API access. Here're the steps in a nutshell:
Create a user group (e.g. Research)
Give access to ComprehendFullAccess
Create a user (e.g.
ComprehendUser) under the newly created user group (i.e.
Research)
Bingo! It should work now.
Here is my code snippet:
# import packages
import boto3
# aws access credentials
AWS_ACCESS_KEY_ID = 'your-access-key'
AWS_SECRET_ACCESS_KEY = 'your-secret-key'
comprehend = boto3.client('comprehend',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name='us-east-1')
test_language_string = "This is a test string. I'm hoping that AWS Comprehend can interprete this as english..."
comprehend.detect_dominant_language(Text=test_language_string)
Expected Output
{'Languages': [{'LanguageCode': 'en', 'Score': 0.9753355979919434}],
'ResponseMetadata': {'RequestId': 'd2ab429f-6ff7-4f9b-9ec2-dbf494ebf20a',
'HTTPStatusCode': 200,
'HTTPHeaders': {'x-amzn-requestid': 'd2ab429f-6ff7-4f9b-9ec2-dbf494ebf20a',
'content-type': 'application/x-amz-json-1.1',
'content-length': '64',
'date': 'Mon, 07 Feb 2022 16:31:36 GMT'},
'RetryAttempts': 0}}
UPDATE: Thanks for all the feedback y'all! It turns out us-west-1 doesn't support comprehend. Switching to a different availability zone did the trick, so I would recommend anyone with similar problems try different zones before digging too deep into permissions//access keys.

Why can't I run my ECS task from AWS Lambda?

I am using Amazon Web Services and trying to run an ECS Task Definition on a Cluster triggered from a Lambda.
When I run this task manually in the ECS console and chose all of the same options as I'm passing to run_task, it runs just fine. I see logs in Cloudwatch and the effects of the task (updaing a database) have happened as expected. But when I run the task from a Lambda it does not work, but also gives me no errors that I can see.
Here's the Lambda definition:
import boto3
def lambda_handler(event, context):
print("howMuchSnowDoUpdate")
client = boto3.client('ecs')
response = client.run_task(
cluster='HowMuchSnow',
taskDefinition='HowMuchSnow:2',
count=1,
launchType='FARGATE',
networkConfiguration={
'awsvpcConfiguration': {
'subnets': [
'subnet-ebce7c8c',
],
'securityGroups': [
'sg-03bb63bf7b3389d42',
],
'assignPublicIp': 'DISABLED'
}
},
)
print(response)
I have given the Lambda's IAM role the policy of ECSFull. Before I did I was getting an expected permission denied when running run_task. But once I added that policy, the Lambda runs just fine with no errors reported and this is the response that I get from that print(response) line:
{'tasks': [{'taskArn': 'arn:aws:ecs:us-east-1:221691463461:task/10b2473f-482d-4f75-ab43-3980f6995b17', 'clusterArn': 'arn:aws:ecs:us-east-1:221691463461:cluster/HowMuchSnow', 'taskDefinitionArn': 'arn:aws:ecs:us-east-1:221691463461:task-definition/HowMuchSnow:2', 'overrides': {'containerOverrides': [{'name': 'HowMuchSnow'}]}, 'lastStatus': 'PROVISIONING', 'desiredStatus': 'RUNNING', 'cpu': '256', 'memory': '512', 'containers': [{'containerArn': 'arn:aws:ecs:us-east-1:221691463461:container/9a76562b-1fef-457f-ae04-0f0eb4003e7b', 'taskArn': 'arn:aws:ecs:us-east-1:221691463461:task/10b2473f-482d-4f75-ab43-3980f6995b17', 'name': 'HowMuchSnow', 'lastStatus': 'PENDING', 'networkInterfaces': []}], 'version': 1, 'createdAt': datetime.datetime(2019, 6, 17, 14, 57, 29, 831000, tzinfo=tzlocal()), 'group': 'family:HowMuchSnow', 'launchType': 'FARGATE', 'platformVersion': '1.3.0', 'attachments': [{'id': 'e6ec4941-9e91-47d1-adff-d406f28b1931', 'type': 'ElasticNetworkInterface', 'status': 'PRECREATED', 'details': [{'name': 'subnetId', 'value': 'subnet-ebce7c8c'}]}]}], 'failures': [], 'ResponseMetadata': {'RequestId': '3a2506ef-9110-11e9-b57a-d7e334b6f5f7', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '3a2506ef-9110-11e9-b57a-d7e334b6f5f7', 'content-type': 'application/x-amz-json-1.1', 'content-length': '1026', 'date': 'Mon, 17 Jun 2019 14:57:29 GMT'}, 'RetryAttempts': 0}}
To my eyes this looks alright. But the task never actually runs. I do see a pending task in tasks list in the ECS console for my cluster briefly. But it runs not nearly as long as the actual task should run. It produces no logs in CloudWatch like it does when I run manually. I see no errors in the logs either.
One thing I will note is that I have to pick a VPC when running the task manually from the console but that's not a valid argument to boto3's ECS run_task function so I don't pass it.
Anyone know what might be going wrong or where I might look for information?
Here's what works for me.
When setting up Lambda:
Role must have ECS run task abilities
Don't specify a VPC in the Lambda function settings itself
Here's the Lambda code (replacing subnets, security groups, etc. for your own).
import boto3
client = boto3.client('ecs')
cluster_name = "demo-cluster"
task_definition = "demo-task:1"
def lambda_handler(event, context):
try:
response = client.run_task(
cluster=cluster_name,
launchType = 'FARGATE',
taskDefinition=task_definition,
count = 1,
platformVersion='LATEST',
networkConfiguration={
'awsvpcConfiguration': {
'subnets': [
'subnet-0r6gh701',
'subnet-a73d7c10'
],
'securityGroups': [
"sg-54cb123f",
],
'assignPublicIp': 'ENABLED'
}
})
print(response)
return {
'statusCode': 200,
'body': "OK"
}
except Exception as e:
print(e)
return {
'statusCode': 500,
'body': str(e)
}
I had this problem and it turned out that I had commented out the CMD line at the end of my Dockerfile during debugging. As such the lambda ran, but no ECS task was logged. Uncommenting the CMD led to the ECS task running and logging again.

Get PermissionsBoundary based on Roles

I am trying to invoke IAM.Client.list_users AWS documentation in my lambda . As per the documentation, the document contains
'PermissionsBoundary': {
'PermissionsBoundaryType': 'PermissionsBoundaryPolicy',
'PermissionsBoundaryArn': 'string'
}
But for the call,I am trying to invoke the following API call PermissionsBoundary is missing
client = boto3.client('iam')
roles = client.list_roles()
for role in roles['Roles']:
print(role)
But the response I am getting is
{
'Path': '/service-role/',
'RoleName': 'send-sns-1',
'RoleId': 'ABCDEF123456ACBD',
'Arn': 'arn:aws:iam::13456798:role/service-role/send-sns-1',
'CreateDate': datetime.datetime(2017, 9, 4, 15, 22, 50, tzinfo = tzlocal()),
'AssumeRolePolicyDocument': {
'Version': '2012-10-17',
'Statement': [{
'Effect': 'Allow',
'Principal': {
'Service': 'lambda.amazonaws.com'
},
'Action': 'sts:AssumeRole'
}]
},
'MaxSessionDuration': 3600
}
The role of lambda function has IAMFullAccess permission.
What is that I am missing, to get 'PermissionsBoundary': {....}
The documentation is wrong, and only GetRole and GetUser currently display the permissions boundary. I've filed an issue about it here but in the meantime I think you'll need to issue GetUser/GetRole repeatedly for every user/role in your account if you want to enumerate all boundaries.