I am trying to use boto3 from within AWS lambda function in order to do post_text to a Lex chat bot.
Python code:
client = boto3.client('lex-runtime')
data = "string input"
response = client.post_text(
botName='xxx',
botAlias='yyy',
userId='id',
inputText= data)
but i get:
An error occurred (AccessDeniedException) when calling the PostText
operation: User: arn:aws:sts::111111111:assumed-
role/functionName/functionName is not authorized to perform: lex:PostText on
resource: arn:aws:lex:us-east-1:111111111:bot:xxx:yyyy"
So i set up IAM rule an and policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lex:PostText"
],
"Resource": [
"arn:aws:lex:us-east-1:111111111:bot:xxx:yyyy"
]
}
]
}
Trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
But it still doesn't work and i get the same error.
I experienced the same issue recently.
It is most certainly related to the permissions assigned to the IAM role that you're using when running the Lambda function.
The easiest way to resolve this is below:-
Open the Lambda function on the AWS Console.
Scroll down to the "Execution role" section.
Click the link under the role to view the role in a new window. It
should look something like this: "View the role".
In the new window under the permissions tab click on "Attach
policies".
This takes you to a new screen. On this screen filter the listed
policies by typing in "lex" in the input field.
The filtered list will contain a policy call "AmazonLexRunBotsOnly".
Attach this policy to your role.
Save the changes and make your way back to your lambda function.
Save the lambda function and retest.
This will resolve your issue.
Related
I try to access dynamodb via boto3 (Python) in AWS. Got this working on my local machine. As I understand in AWS running, it just uses IAM roles to get access. But it does not work.
Lambda execution failed with status 200 due to customer function error: An error occurred (AccessDeniedException) when calling the Scan operation:
User: arn:aws:sts::021517822274:assumed-role/CodeStar-tt-api-subjects-Execution/
awscodestar-tt-api-subjects-lambda-HelloWorld is not authorized to perform: dynamodb:
Scan on resource: arn:aws:dynamodb:us-east-1:021517822274:table/tt-subjects.
Quite the same question was send here:
How to solve (AccessDeniedException) when calling the Scan operation: User: arn:aws:sts... is not authorized to perform: dynamodb:Scan on resource.."?
And I applied the suggested AmazonDynamoDBFullAccess policy. Tried also those:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_specific-table.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_lambda-access-dynamodb.html
My own added policy (in addition) is:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListAndDescribe",
"Effect": "Allow",
"Action": [
"dynamodb:List*",
"dynamodb:DescribeReservedCapacity*",
"dynamodb:DescribeLimits",
"dynamodb:DescribeTimeToLive"
],
"Resource": "*"
},
{
"Sid": "SpecificTable",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGet*",
"dynamodb:DescribeStream",
"dynamodb:DescribeTable",
"dynamodb:Get*",
"dynamodb:Query",
"dynamodb:Scan"
],
"Resource": "arn:aws:dynamodb:*:*:table/tt-subjects"
}
]
}
But I still got the same error.
Does it take a long time to apply the policies or what may still cause that?
Now I found the answer. As I created my lambda with codestar, it also created a permission boundary.
How to solve this issue:
remove the boundary (not recommended)
extend the boundary, like this:
Edit the boundary of your lambda:
Open console for Lambda
Go to tab configuration
In Execution Role, open the link to your role
Now you are in IAM role editor. Scroll down to Permission boundary
Copy that name (there is no link)
Go in IAM menu to Policies
Search for the copied name
Edit (extend) the policy.
In my case regarding dynamodb, I scrolled down to sid 6 (might differ for you). It is an Allow block with many simple entries and a * as resource.
So I extended this block with dynamodb entries. Now it looks like this:
...
{
"Sid": "6",
"Effect": "Allow",
"Action": [
"apigateway:GET",
"cloudtrail:CreateTrail",
"cloudtrail:StartLogging",
"ec2:Describe*",
"lambda:ListFunctions",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:PutLogEvents",
"sns:Get*",
"sns:List*",
"sns:Publish",
"sns:Subscribe",
"xray:Put*",
"dynamodb:BatchGet*",
"dynamodb:DescribeStream",
"dynamodb:DescribeTable",
"dynamodb:Get*",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWrite*",
"dynamodb:CreateTable",
"dynamodb:Delete*",
"dynamodb:Update*",
"dynamodb:PutItem",
"dynamodb:List*",
"dynamodb:DescribeReservedCapacity*",
"dynamodb:DescribeLimits",
"dynamodb:DescribeTimeToLive"
],
"Resource": [
"*"
]
},
...
Many thanks to the contributors helped me!
Good day.
I tried getDashboardEmbedUrl() and it works fine with the UserArn set to the ADMIN user in my Quicksight account. Now I am trying to use the generateEmbedUrlForRegisteredUser(). But it gives the following error:
Error executing "GenerateEmbedUrlForRegisteredUser" on "https://quicksight.eu-west-1.amazonaws.com/accounts/971170084134/embed-url/registered-user"; AWS HTTP error: Client error: `POST https://quicksight.eu-west-1.amazonaws.com/accounts/xxxxxxxxxxxx/embed-url/registered-user` resulted in a `404 Not Found` response:
{"Message":"User arn:aws:quicksight:eu-west-1:xxxxxxxxxxxx:user/default/jjordaan does not exist.","RequestId":"5c310250- (truncated...)
ResourceNotFoundException (client): User arn:aws:quicksight:eu-west-1:xxxxxxxxxxxx:user/default/jjordaan does not exist. - {"Message":"User arn:aws:quicksight:eu-west-1:xxxxxxxxxxxx:user/default/jjordaan does not exist.","RequestId":"5c310250-a1bb-413f-b2d7-f07fdb91e027","ResourceType":null}
GenerateEmbedUrlForRegisteredUser Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"quicksight:GenerateEmbedUrlForRegisteredUser",
"quicksight:RegisterUser"
],
"Resource": "*"
}
]
}
EmbeddingQuicksightAssumeRole policy:
{
"Version": "2012-10-17",
"Statement":
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::971170084134:role/GenerateEmbedUrlForRegisteredUser"
}
}
Also attempted to create a new Quicksight user, but no luck. The URL generation error is the same. What could I be doing wrong? Thanks.
Regards.
Jarrett
The error message says the user does not exist: User arn:aws:quicksight:eu-west-1:xxxxxxxxxxxx:user/default/jjordaan does not exist
You need to register the user with Quicksight before that user can do anything with Quicksight. Requesting a dashboard and registering users are separate methods with separate permissions.
For example:
client.register_user(
AwsAccountId=AWS_ACCOUNT_ID,
Namespace="default",
IdentityType="IAM",
IamArn=f"arn:aws:iam::{AWS_ACCOUNT_ID}:role/{QUICKSIGHT_DASHBOARD_ROLE_NAME}",
UserRole="READER",
SessionName=user.email,
Email=user.email
)
QUICKSIGHT_DASHBOARD_ROLE_NAME is a role that is allowed to embed a dashboard (such as GenerateEmbedUrlForRegisteredUser).
To get a dashboard URL
assume the role and get credentials
use credentials to get the dashboard embed URL
response = client.assume_role(
RoleArn=f"arn:aws:iam::{AWS_ACCOUNT_ID}:role/{QUICKSIGHT_DASHBOARD_ROLE_NAME}",
RoleSessionName=user.email
)
creds = response["Credentials"]
# get the access key, the secret key, and the session token from the response
client = boto3.client(
"quicksight",
region_name=QUICKSIGHT_REGION,
aws_access_key_id=creds["AccessKeyId"],
aws_secret_access_key=creds["SecretAccessKey"],
aws_session_token=creds["SessionToken"],
)
response = client.get_dashboard_embed_url(
AwsAccountId=AWS_ACCOUNT_ID,
DashboardId=dashboard_id,
IdentityType="IAM",
SessionLifetimeInMinutes=60,
)
url = response.get("EmbedUrl")
I used the above CLI command but got an error in the console, please find the attached screenshot of the error
Please find below function policy of lambda:
{ "Version": "2012-10-17", "Id": "default", "Statement": [
{
"Sid": "events-access",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:096280016729:function:leto_debug_log",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:events:us-east-1:096280016729:rule/*"
}
}
} ] }
I followed the answer from the below link but still got an error:
Allow all cloudwatch event rules to have access to lambda function
Perhaps a clue to this, is that a CloudWatch Event rule name of * does not appear to be valid. For example, if you try to delete this rule in the AWS lambda console area, you will get an error like this on the trigger UI area:
It would be nice if this approach was formally supported in some way, but I don't think it is. idk
I created a new IAM role through Cognito during the setup process. Here is that policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:publish"
],
"Resource": [
"*"
]
}
]
}
In the trust relationship tab, it shows "The identity provider(s) cognito-idp.amazonaws.com" and it has a condition for sts:Externalid.
I tried adding a policy for FullEC2Access but so far I have not been able to get this IAM role to show up in the drodown when creating a new EC2 instance.
I will be using this instance for a new web app which will utilize Cognito. Any feedback appreciated.
I am trying to set a group policy with IAM to provide access to the users at the particular region with specific vpc. As referring the AWS documents,trying to use vpc ID to filter the instances, since the resource-tag is not working with ec2 ( ResourceTag would be better option if its working with EC2).
Created a following rule for the same, but it did not help,
{ "Version": "2012-10-17",
"Statement": [ {
"Action": [
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:Describe*" ],
"Resource": "*",
"Effect": "Allow",
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:us-west-2:*:vpc/vpc-123456"
}
}
} ] }
the result shows "An error occurred fetching Instance data" on EC2 page.
May I have any suggestions to fix this ?
Thank you
Thank you for you reply Rico :-)
Unfortunately,The given policy is did not work for me as per my requirement.
Need to give access to a user for particular region and user should have access to the instance which based on particular Resource tag or VPC or subnet or security group.
The user should not have privileges to launch or edit anything and user should able to list out the instances based on the filter as mentioned above to view the instance details (Read-only).
By considering above aspects, I have defined similar policy with dual condition ,since ARN is not working well with Resources for me.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*",
"Condition": {
"StringEquals": {
[
"ec2:Region": "us-west-2",
"ec2:ResourceTag/Name": "Test"
]
}
}
}
]
}
When I use ARN for resource, it's not working for me on below format,
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "arn:aws:ec2:us-west-2:1234567890:*/*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Name": "Test"
}
}
}
]
}
I have tried with filtering Instances by using Resource tag, Instance ID, Security group and subnet.
Now I understand from your reply that VPC filter is not possible as of now.
Please refer the image for the Resource Tag of my instance.
Your prompt response will be highly appreciated.
Thanks in advance!
I have discussed with AWS Solution architect and the given following update,
The Describe* APIs for EC2 cannot be restricted to certain resources yet.
In the initial releases of resource-level permissions for EC2 we focused on those actions that create new or modify existing resources.
See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-policies-for-amazon-ec2.html#ec2-supported-iam-actions-resources for the full list of actions in EC2 that support resource-level permissions.
We are working to extend the support for resource-level access control to more actions but we cannot provide with a date when this would be available for Describe* APIs.
Whether Resource-level permissions are supported or not depends on the action, see the link above.
In particular, restricting EC2 Describe* Actions to resources is not possible as of now, but the above ARN can be used to restrict Actions that modify resources.
Resource Tag,subnet , security-group and vpc are supported in the "Condition" section of an IAM policy statement, but only for certain Actions – see http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-policies-for-amazon-ec2.html#amazon-ec2-keys for the available keys. However, Resource Tag,subnet , security-group and vpc are not supported in Conditions for the Describe* APIs.
Finally, I just ending with workaround by restricting a user with only region.
So this is not possible using IAM at the moment, the only way is to use a ResourceTag. Curious as to why they are not working for you? I've have been interacting with AWS Support and this is their response:
Unfortunately, there is not a way to do this at this time. While we do
now offer resource level permissions for EC2 resources, (more info
here...
http://aws.typepad.com/aws/2013/07/resource-permissions-for-ec2-and-rds-resources.html)
conditionally controlling access based on a specif VPC is not
supported.
This is because this link: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-policies-for-amazon-ec2.html#ec2-supported-iam-actions-resources shows that there are a limited number of EC2 API actions supported and none of them support VPC as a ARN.
There's also a limitation on "ec2:Describe*", which cannot be specified by a resource ARN at all, and cannot be conditionally controlled.
The workaround is to use the conditional statement "ResourceTag/tag-key" which is usable by most API calls. So you can potentially tag your instances with "Control":"Allow" and don't include the create or remove tag privileges in the policy to be attached to the user in question. Your policy would look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances",
"ec2:TerminateInstances"
],
"Resource": "arn:aws:ec2:REGION:ACCOUNTNUMBER:instance/*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Control": "Allow"
}
}
}
]
}
Then you can restrict the user to launch instance just in a particular VPC using its subnet-id:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:region:account:instance/*",
"arn:aws:ec2:region:account:subnet/SUBNET-ID-HERE",
"arn:aws:ec2:region:account:volume/*",
"arn:aws:ec2:region:account:network-interface/*",
"arn:aws:ec2:region:account:key-pair/*",
"arn:aws:ec2:region:account:security-group/*",
"arn:aws:ec2:region::image/ami-*"
]
}
]
}
To answer your question for a specific region, IAM policies are already region restricted, so this policy would only work on the specific region where you user that you are trying to restrict is on.
Hope this helps.