Variable in AWS IAM role to grant permissions to Lambda function - amazon-web-services

I am trying to figure out if it is possible to design an AWS IAM role that would dynamically grant permission to resource based on the name of the calling resource. For example I currently have a role that grants a Lambda function permission to create and write CloudWatch logs, which looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CWLog",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:log-group:/aws/lambda/MyLambdaFunction*"
}
}
I am wondering if there is a way to substitute the string MyLambdaFunction for the name of the calling Lambda function using some ${aws:NameOfTheLambdaFunction} variable, so that I can have a generic policy allowing functions to write only to their specific CW log groups that I can attach to different Lambda roles - with the resource statement looking like: "Resource": "arn:aws:logs:*:*:log-group:/aws/lambda/${aws:NameOfTheLambdaFunction}*"
Is something like this possible?

You're referring to an IAM policy variable which provides you the name of the calling Lambda function.
Unfortunately, this policy variable does not currently exist and so this isn't possible.

Related

How to restrict AWS lambda access to only one role

I have created one lambda. I need to provide access to only one role that is created for this lambda i.e. only this role should have the invoke access. There may be other roles in account which may have invoke access on all lambdas but I want to restrict those roles not to access my lambda.
Can anyone please suggest a way to achieve this behavior?
A resource-based policy attached to a lambda function will work as Maurice commented.
Below is the sample policy. The action specified in the policy statement is explicitly denied to all principals except for the one specified. Only lambda_role is allowed to invoke testfunction lambda using the below resource-based policy.
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "0001",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::659266464590:role/service-role/lambda_role"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:659266464590:function:testfunction"
}
]
}

AWS CloudWatch - Log group does not exist

I'm getting this error message when trying to see the log file in AWS CloudWatch for my AWS Lambda function.
An error occurred while describing log streams.
The specified log group does not exist.
Log group does not exist
The specific log group: /aws/lambda/xxxxx does not exist in this account or region.
By the way, I'm using the Singapore region.
Make sure that your Lambda function's execution role has sufficient permissions to write logs to CloudWatch, and that the log group resource in the IAM policy includes your function's name.
In the IAM console, review and edit the IAM policy for the execution role to make sure that:
The write actions CreateLogGroup and CreateLogStream are allowed. You should attach these policies in the IAM roles of the Lambda function
Note: If you don't need custom permissions for your function, you can attach the managed policy AWSLambdaBasicExecutionRole, which allows Lambda to write logs to CloudWatch.
The AWS Region specified in the Amazon Resource Name (ARN) is the
same as your Lambda function's Region.
The log-group resource includes your Lambda function name. For
example, if your function is named myLambdaFunction, the log-group is
/aws/lambda/myLambdaFunction.
Here is an example of the permissions in the JSON format
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:region:accountId:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
" arn:aws:logs:region:accountId:log-group:/aws/lambda/functionName:*"
]
}
]
}

How to create an IAM role of specific type using boto3?

I'm trying to lock down a user to a specific VPC in AWS and following How to Help Lock Down a User’s Amazon EC2 Capabilities to a Single VPC | AWS Security Blog.
It is mentioned that we need to create an IAM role with name VPCLockDown of type AWS Service
and add the services for which the role needs access to. like ec2, lambda etc.
I was trying to create this role programatically using boto3.
I checked the create_role documentation for creating a role using boto3.
However, they haven't mentioned anything to specify the type of role and the services that I can specify that the role should have access to.
Is there any way to specify these items while creation of the IAM role using boto3
Edit1:
I tried creating a service_linked_role as per Sudarshan Rampuria's answer like
response = iam.create_service_linked_role(
AWSServiceName='ec2.amazonaws.com',
)
But getting the following error:
An error occurred (AccessDenied) when calling the
CreateServiceLinkedRole operation: Cannot find Service Linked Role
template for ec2.amazonaws.com
You can use create_service_linked_role() function boto3 to link a role to a service.
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iam.html#IAM.Client.create_service_linked_role
Here is a policy that allows a specific IAM User to launch an instance (RunInstances), but only in a given VPC:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2RunInstancesVPC",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:ap-southeast-2:111111111111:subnet/*",
"Condition": {
"StringEquals": {
"ec2:vpc": "arn:aws:ec2:ap-southeast-2:111111111111:vpc/vpc-abcd1234" <--- Change this
}
}
},
{
"Sid": "RemainingRunInstancePermissions",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:ap-southeast-2:111111111111:instance/*",
"arn:aws:ec2:ap-southeast-2:111111111111:volume/*",
"arn:aws:ec2:ap-southeast-2::image/*",
"arn:aws:ec2:ap-southeast-2::snapshot/*",
"arn:aws:ec2:ap-southeast-2:111111111111:network-interface/*",
"arn:aws:ec2:ap-southeast-2:111111111111:key-pair/*",
"arn:aws:ec2:ap-southeast-2:111111111111:security-group/*"
]
}
]
}
You might need to change the Region. (I tested it in the Sydney region.)
For anyone trying to do this for Lambda, we get the similar error mentioned by the question author under "Edit". Lambda doesn't have a service linked role. You can see from the AWS Lambda documentation that "create-role" is used for creating lambda execution role.
You can also see here that only Lambda#Edge has service linked role.
One just needs to use use boto3 create-role with a policy document
response = iam_client.create_role(
RoleName="some-role-name",
AssumeRolePolicyDocument='{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}',
Description='Lambda role'
)

aws s3 upload fail only at production envrionment, but success at local environment

I tried to upload image using aws-sdk, multer-s3.
In my local environment, uploading image was succeed, but in production environment(aws lambda), it fail with error status 403 forbidden.
But my aws credential key and secret-key is same as local environment. also i checked aws key in production environment successfully.
I think difference between two other environment is nothing.What am I missing?
I have even tried setting aws key in my router code like below, but it also failed.
AWS.config.accessKeyId = 'blabla';
AWS.config.secretAccessKey = 'blalbla';
AWS.config.region = 'ap-northeast-2';
and here is my policy
{
"Id": "Policy1536755128154",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1536755126539",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::elebooks-image/*",
"Principal": "*"
}
]
}
Update your attached s3 bucket policy to a user according to below policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::YOUR-BUCKET",
"arn:aws:s3:::YOUR-BUCKET/*"
]
}
]
}
it's working on my server.
I haven't worked with AWS Lambda but I am familiar with S3. When you're using the AWS SDK in your local environment, you're probably using the root user with default full access, so it will just work.
With Lambda however, according to the following extract from the documentation, you need to make sure that the IAM role you specified when you created the Lambda function has the appropriate permissions to do an s3:putObject to that bucket.
Permissions for your Lambda function – Regardless of what invokes a Lambda function, AWS Lambda executes the function by assuming the IAM role (execution role) that you specify at the time you create the Lambda function. Using the permissions policy associated with this role, you grant your Lambda function the permissions that it needs. For example, if your Lambda function needs to read an object, you grant permissions for the relevant Amazon S3 actions in the permissions policy. For more information, see Manage Permissions: Using an IAM Role (Execution Role).
See Writing IAM policies: How to grant access to an S3 bucket

AWS - How to restrict the user to delete or modify the lambda function created by others

I need to add a new AWS user to use lambda function, but I don't want him to delete or modify the lambda functions created by the other users. If I can also not show the other existing lambda functions to him, it will be the most ideal solution. How should I set up this in IAM policy?
As per AWS docs, you'll want an IAM policy similar to the following. Replace the relevant AWS values.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PermissionToInvoke",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:AWS_REGION:AWS_ACCOUNT_ID:function:LAMBDA_FUNCTION_NAME"
}
]
}