giving all lambda function access to secretmanager - aws-lambda

I want to access aws secret manager in all my lambda functions(AWS::Serverless::Function). Currently, I have to give individual lambda function reference like below. Since I have many lambda functions it is tedious. I tried "Service": "lambda.amazonaws.com" but it didn't work.
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal" : {
"AWS" : ["arn:aws:sts::xxxxxxx:assumed-role/employer-api-getAllEmployeesFunctionRole-xxxxx/employer-api-4-getAllEmployeesFunction-xxxxx",
"arn:aws:sts::xxxxxxx:assumed-role/employee-backend-getEmployeeByIdFunctionRole-xxxxx/employee-backend-getEmployeeByIdFunction-xxxxx"
]
},
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "*"
} ]
}

You can create a policy(Like below) and attach it to your lambda's execution role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}
]
}
This will allow your lambda function to get secret value of any Secret stored in secret manager.
According to best practice we should only allow our lambda or any other aws service to give minimal access required.
So if your lambda needs access to only one Secret manager it is best you pass the ARN of that secret in below policy and attach it to your role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "<ARN of secret required by lambda>"
}
]
}
You can use AWS CDK IAM module to easily create role and policies.

Related

AWS IAM Roles: Policy with permissions only over the instance itself and not every resource

I'll try to explain my issue the best I can.
I want to create an IAM Role with my own RebootPolicy that, when attached to an EC2 instance, allows that instance to reboot itself (but only itself). Currently the only thing I can do is create a role with a policy that allows Reboot in all instances.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:RebootInstances",
"Resource": "*"
}
]
}
I know I could technically add the specific id of the instance to the policy, but the idea is that I use the policy in any instance I want and not just an specific one. I tried following the documentation at https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonec2.html but I don't know how to implement it.
Any ideas?
Thanks in advance!
You can self reference EC2 by using ec2:SourceInstanceARN IAM policy variable.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:RebootInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ARN": "${ec2:SourceInstanceARN}"
}
}
}
]
}
I think you can use: $(aws:userid)
IAM Policy Elements: Variables and Tags says:
aws:userid will be set to role-id:ec2-instance-id where role-id is the unique id of the role and the ec2-instance-id is the unique identifier of the EC2 instance.

AWS Lambda called via Cloudfront in front of S3 bucket can't assume role for Cognito User Pool to authenticate

I have an AWS Lambda that is run as a viewer request on a CloudFront instance that restricts access to an S3 bucket setup for static hosting of a website. It uses a Cognito User Pool to restrict access and verifies the credentials via AdminInitiateAuth.
The lambda runs fine using the test data directly obtained from logging the CloudFront event, however when actually called via the trigger from CloudFront I get the error:
An error occurred (AccessDeniedException) when calling the AdminInitiateAuth operation:
User: arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/cloudfront_trigger_s3_auth_http_service/us-east-1.s3_service_resources_auth
is not authorized to perform: cognito-idp:AdminInitiateAuth on resource:
arn:aws:cognito-idp:us-west-2:<AWS_ACCOUNT_ID>:userpool/<USER_POOL_ID>
I've tried expanding my trust relationship and making sure that AWS STS can assume the role when it needs to.
cloudfront_trigger_s3_auth_http_service role trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"cognito-idp.amazonaws.com",
"edgelambda.amazonaws.com",
"sts.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
arcimoto-service-resources-user-pool-auth policy attached to cloudfront_trigger_s3_auth_http_service role that allows cognito access
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"cognito-idp:AdminInitiateAuth",
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::511596272857:role/cloudfront_trigger_s3_auth_http_service/us-east-1.s3_service_resources_auth",
"arn:aws:cognito-idp:us-east-1:511596272857:userpool/us-east-1_sES7sBpcg"
]
}
]
}

How to access aws resources created in other account

In my use case, I want to access DynamoDB table created in AWS account A and Lambda created in account B. For this I have followed many references on Internet which suggests me to use AWS assume role feature.
I have added following permission in Lambda execution role
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::aws-account-A-number:role/test-db-access"
}
}
Following is the trust relationship of Lambda
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::aws-account-A-number:root"
},
"Action": "sts:AssumeRole"
}
]
}
In account A, I have created role(test-db-access) for allowing others to access this account and added AmazonDynamoDBFullAccess and AdministratorAccess policies. Following is the trust relationship I have added in this account
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::aws-account-B-number:role/sam-dev-test-
TestLambda-LambdaRole-1FH5IC18J0MYT"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Following is the Java code I have added to access Dynamo DB instance
AssumeRoleRequest assumeRequest = new AssumeRoleRequest()
.withRoleArn("arn:aws:iam::aws-account-A-number:role/test-db-access").withRoleSessionName("cross_acct_lambda").withDurationSeconds(900);
final AWSSecurityTokenService sts = AWSSecurityTokenServiceClientBuilder.standard().withRegion("eu-west-1").build();
final Credentials credentials = sts.assumeRole(assumeRequest).getCredentials();
following is the crash log coming on executing lambda
{
"errorMessage": "User: arn:aws:sts::aws-account-B-number:assumed-role/sam-dev-test-TestLambda-LambdaRole-1FH5IC18J0MYT/sam-dev-test-TestLambda-LambdaFunction-73TVOBN6VXXX is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::aws-account-A-number:role/test-db-access (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 100bd3a3-3f9c-11ea-b642-d3b4d9ff35de)",
"errorType": "com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException"
}
It appears your requirements are:
From an AWS Lambda function in Account-B, access a DynamoDB table in Account-A
To reproduce your situation I did the following:
Created a DynamoDB table in Account-A
Created an IAM Role (Role-A) in Account-A with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": "arn:aws:dynamodb:ap-southeast-2:<Account-A>:table/Inventory"
}
]
}
And this Trust Relationship (pointing to the Role created in the next step):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account-B>:role/role-b"
},
"Action": "sts:AssumeRole"
}
]
}
Created an IAM Role (Role-B) in Account-B for use with the Lambda function, with this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account-A>:role/role-a"
}
]
}
And with this Trust Relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Created an AWS Lambda function in Account-B that will:
Assume Role-A in Account-A
Access the DynamoDB table in Account-A
I'm a Python person, so my function is:
import boto3
def lambda_handler(event, context):
# Assume Role
sts_client = boto3.client('sts')
response = sts_client.assume_role(
RoleArn='arn:aws:iam::<Account-A>:role/stack-role-a',
RoleSessionName='bar')
session = boto3.Session(
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token=response['Credentials']['SessionToken']
)
# Update DynamoDB
dynamodb_client = session.client('dynamodb')
dynamodb_client.update_item(
TableName='Inventory',
Key={'Item': {'S': 'foo'}},
UpdateExpression="ADD #count :increment",
ExpressionAttributeNames = {
'#count': 'count'
},
ExpressionAttributeValues = {
':increment': {'N': '1'},
}
)
I tested this by clicking Test on the Lambda function in Account-B. It successfully updated the DynamoDB table in Account-A.
I suspect the difference is with your trust policies, which appear to be a little bit different.

ec2 instance create fails using IAM role with terraform

I am using terraform to create EC2 instance using IAM profile. With all the proper roles and policies set, I am still getting the error:
UnauthorizedOperation: You are not authorized to perform this operation.status code: 403
Here is my main.tf:
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "aws_test" {
ami = "ami-image"
instance_type = "t2.micro"
iam_instance_profile = "test-role"
}
Here is my aws policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"ec2:InstanceType": [
"t2.micro"
]
}
}
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*"
}
]
}
This is the arn of role which I am using in my main.tf
arn:aws:iam:::role/test-role
On googling, I found articles which tell me this should work, but I seem to be missing something. Any help would be highly appreciated.
Thanks in advance!!
update: I am running this by directly installing terraform on an ec2 machine, not sure if this could be causing a problem
Running the Terraform in the EC2 instance without providing the specific credential will potentially use the Metadata API to retrieve credential.
You can check if you can call the Metadata API inside the instance.
The UnauthorizedOperation means that the user or role running terraform does not have the permissions to make an aws_instance.
Make sure that the user or role running terraform has the proper permissions in AWS IAM

AWS console test user is not able to see admin user lambda functions

For example I am admin of AWS console and there is a user X to whom I need to share some test lambda functions which are created by me, so that he can test in test lambda functions instead of messing with production lambda functions and also I do not want X to see access my lambda functions.
But when I create a test user and login into his console, I am not able to see any of the admin functions in his console, below is my custom policy attached to the test user
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:*",
"cognito-identity:ListIdentityPools",
"cognito-sync:GetCognitoEvents",
"cognito-sync:SetCognitoEvents",
"dynamodb:*",
"events:*",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:PassRole",
"lambda:*",
"logs:*",
"kms:ListAliases"
],
"Resource": "*"
}
]
}
but the same thing does not happened with s3 buckets, I have attached one more policy to the test user for accessing only test s3 bucket, which is working well, below is the policy description.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::test"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::test/*"
]
}
]
}
I made a silly mistake, some one also might encounter it, so I would like to mention it, I have selected a different region in my aws console in testuser account, so it is not showing up, when I select back the region where I have created the lmabda functions it started showing up all the lambda functions.

Resources