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.
Related
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 :)
Looking at the man page for list-secrets, there is no special options to show deleted or not. It does not list deleted secrets. However, the output definition includes a "DeletedDate" timestamp.
The ListSecrets API does not show any option for deleted secrets. But again the response includes a DeletedDate.
The boto3 docs for list_secrets() are the same.
However, in the AWS console I can see deleted secrets. A quick look at the dev tools and I can see my request payload to the Secrets Manager endpoint looks like:
{
"method": "POST",
"path": "/",
"headers": {
"Content-Type": "application/x-amz-json-1.1",
"X-Amz-Target": "secretsmanager.ListSecrets",
"X-Amz-Date": "Fri, 27 Nov 2020 13:19:06 GMT"
},
"operation": "ListSecrets",
"content": {
"MaxResults": 100,
"IncludeDeleted": true,
"SortOrder": "asc"
},
"region": "eu-west-2"
}
Is there any way to pass "IncludeDeleted": true to the CLI?
Is this a bug? Where do I report it? (I know there is a cloudformation bug tracker on github, I assume secretsmanager would have something similar somewhere..?)
Save the following file to ~/.aws/models/secretsmanager/2017-10-17/service-2.sdk-extras.json:
{
"version": 1.0,
"merge": {
"shapes": {
"ListSecretsRequest": {
"members": {
"IncludeDeleted": {
"shape": "BooleanType",
"documentation": "<p>If set, includes secrets that are disabled.</p>"
}
}
}
}
}
}
Then you can list secrets with the CLI as follows:
aws secretsmanager list-secrets --include-deleted
or with boto3:
import boto3
def list_secrets(session, **kwargs):
client = session.client("secretsmanager")
for page in client.get_paginator("list_secrets").paginate(, **kwargs):
yield from page["SecretList"]
if __name__ == "__main__":
session = boto3.Session()
for secret in list_secrets(session, IncludeDeleted=True):
if "DeletedDate" in secret:
print(secret)
This is using the botocore loader mechanism to augment the service model for Secrets Manager, and tell boto3 that "IncludeDeleted" is a parameter for the ListSecrets API.
If you want more detail, I've just posted a blog post explaining what else I tried and how I got to this solution – and thanks to OP, whose dev tool experiments were a useful clue.
Compute environments created via boto3 are not displayed in AWS console. I can see them in the batch_client.describe_compute_environments() call response:
{
'computeEnvironmentName': 'name',
'computeEnvironmentArn': 'arn:aws:batch:us-east-1:<ID>:compute-environment/ml-retraining-compute-env-second',
'ecsClusterArn': 'arn:aws:ecs:us-east-1:<ID>:cluster/ml-retraining-compute-env-second_Batch_b18fcd09-8d7e-351b-bc0f-13ffa83a6b15',
'type': 'MANAGED',
'state': 'ENABLED',
'status': 'INVALID',
'statusReason': "CLIENT_ERROR - The security group 'sg-2436d85c' does not exist",
'computeResources': {
'type': 'EC2',
'minvCpus': 0,
'maxvCpus': 512,
'desiredvCpus': 24,
'instanceTypes': [
'optimal'
],
'subnets': [
'subnet-fa22de86'
],
'securityGroupIds': [
'sg-2436d85c'
],
'instanceRole': 'arn:aws:iam::<ID>:instance-profile/ecsInstanceRole',
'tags': {
'component': 'ukai-training-pipeline',
'product': 'Cormorant',
'jira_project_team': 'CORPRJ',
'business_unit': 'Threat Systems Products',
'created_by': 'ml-pipeline'
}
},
'serviceRole': 'arn:aws:iam::<ID>:role/AWSBatchServiceRole'
}
but the Compute Environments table on the Batch page in AWS console UI does not show anything. The table is empty. When I try to create compute environment with the same name again via boto3 call, I get this response:
ERROR - Error setting compute environment: An error occurred
(ClientException) when calling the CreateComputeEnvironment operation: Object already exists.
Based on the comments, the issue was the use of different region in the console.
The solution was to change the region.
I am getting a 403 PERMISSION_DENIED response from GCP when running the deployment manager to create a deployment that creates a service account and sets IAM policy for it using the cloud resource manager API. Here is the setIamPolicy template for this:
{
'resources': [
{
'name': context.env['name'],
'action': 'gcp-types/cloudresourcemanager-v1:cloudresourcemanager.projects.setIamPolicy',
'properties': {
'resource': context.properties['resource'],
'policy': {
'bindings': context.properties['bindings']
}
}
}
]
}
Response from GCP:
'{"ResourceType":"gcp-types/cloudresourcemanager-v1:cloudresourcemanager.projects.setIamPolicy","ResourceErrorCode":"403","ResourceErrorMessage":{"code":403,"message":"The
caller does not have permission","status":"PERMISSION_DENIED","statusMessage":"Forbidden","requestPath":"https://cloudresourcemanager.googleapis.com/v1/projects/project-name#project-name.iam.gserviceaccount.com:setIamPolicy","httpMethod":"POST"}}'
FYI: The robot account (12345#cloudservices.gserviceaccount.com) is given project owner permissions in IAM.
The right way to do this is:
{
# Set the IAM policy by patching the existing policy with the
# config contents.
'name': policy_add_name,
'action': 'gcp-types/cloudresourcemanager-v1:cloudresourcemanager.projects.setIamPolicy',
'properties':
{
'resource': project_id,
'policy': '$(ref.' + policy_get_name + ')',
'gcpIamPolicyPatch': {
'add': policies_to_add,
}
}
}
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'}