Python3.7 script to export CloudWatch logs to S3 - python-3.x

I am using below code to copy CloudWatch logs to S3:-
import boto3
import collections
from datetime import datetime, date, time, timedelta
region = 'eu-west-1'
def lambda_handler(event, context):
yesterday = datetime.combine(date.today()-timedelta(1),time())
today = datetime.combine(date.today(),time())
unix_start = datetime(1970,1,1)
client = boto3.client('logs')
response = client.create_export_task(
taskName='Export_CloudwatchLogs',
logGroupName='/aws/lambda/stop-instances',
fromTime=int((yesterday-unix_start).total_seconds() * 1000),
to=int((today -unix_start).total_seconds() * 1000),
destination='bucket',
destinationPrefix='bucket-{}'.format(yesterday.strftime("%Y-%m-%d"))
)
return 'Response from export task at {} :\n{}'.format(datetime.now().isoformat(),response)
I gave below policy to role:-
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogStreams",
"logs:CreateExportTask",
"logs:DescribeExportTasks",
"logs:DescribeLogGroups"
],
"Resource": [
"arn:aws:logs:*:*:*"
]
}
]
}
EOF
2nd policy:-
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetBucketAcl"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::${var.source_market}-${var.environment}-${var.bucket}/*"],
"Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } }
}
]
}
EOF
I am getting below error if I execute this in AWS console:-
{
"errorMessage": "An error occurred (InvalidParameterException) when calling the CreateExportTask operation: GetBucketAcl call on the given bucket failed. Please check if CloudWatch Logs has been granted permission to perform this operation.",
"errorType": "InvalidParameterException"
I have referred many blocks after appending role with appropriate policies.

Check the encryption settings on your bucket. I had the same problem and it was because I had it set to AWS-KMS. I was getting this error with the same permissions you have and then it started working as soon as I switched the encryption to AES-256

It seems like an issue with s3 bucket permissions. You need to attach this policy to your s3 bucket. Please amend the policy by changing the bucket name and aws region for cloudwatch.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:GetBucketAcl",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-exported-logs",
"Principal": { "Service": "logs.us-west-2.amazonaws.com" }
},
{
"Action": "s3:PutObject" ,
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-exported-logs/random-string/*",
"Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } },
"Principal": { "Service": "logs.us-west-2.amazonaws.com" }
}
]}
https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/S3ExportTasksConsole.html

I had the same error, the issue was that I put on "destination" parameter something like bucket/something while on the policy I just had bucket, so removing the something prefix on the parameter fixed the problem, so check that the policy and the parameter match.

Related

How can i get putobject access to s3 from specific ec2 instance

I created S3 static web - public bucket and by default all the ec2 instance that i have in my account can upload files to the s3 bucket.
My goal is to limit the access to upload files to the bucket just from spesific instance (My bastion instance) .
So I created a role with all s3 permission and attach the role to my bastion instance , than I put this policy in the bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::name/*"
},
{
"Sid": "allow only OneUser to put objects",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::3254545218:role/Ec2AccessToS3"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::name/*"
}
]
}
But now all the ec2 instance include the bastion instance cant upload files to the s3 bucket..
Im trying to change this arn line:
"NotPrincipal": {
"AWS": "arn:aws:iam::3254545218:role/Ec2AccessToS3"
To user arn and its work .. But I want this is work on the role
I was able to do the operation on a specific user but not on a specific instance (role).
What Im doing wrong?
Refer to the "Granting same-account bucket access to a specific role" section of this AWS blog. The gist is as given below.
Each IAM entity (user or role) has a defined aws:userid variable. You will need this variable for use within the bucket policy to specify the role or user as an exception in a conditional element. An assumed-role’s aws:userId value is defined as UNIQUE-ROLE-ID:ROLE-SESSION-NAME (for example, AROAEXAMPLEID:userdefinedsessionname).
To get AROAEXAMPLEID for the IAM role, do the following:
Be sure you have installed the AWS CLI, and open a command prompt or shell.
Run the following command: aws iam get-role -–role-name ROLE-NAME.
In the output, look for the RoleId string, which begins with AROA.You will be using this in the bucket policy to scope bucket access to only this role.
Use this aws:userId in the policy,
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*",
"111111111111"
]
}
}
}
]
}
{
"Role": {
"Description": "Allows EC2 instances to call AWS services on your behalf.",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"MaxSessionDuration": 3600,
"RoleId": "AROAUXYsdfsdfsdfsdf
L",
"CreateDate": "2023-01-09T21:36:26Z",
"RoleName": "Ec2AccessToS3",
"Path": "/",
"RoleLastUsed": {
"Region": "eu-central-1",
"LastUsedDate": "2023-01-10T05:43:20Z"
},
"Arn": "arn:aws:iam::32sdfsdf218:role/Ec2AccessToS3"
}
}
I just want to update , Im trying to give access to spesific user instead ..
this is not working to..
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::name.com",
"arn:aws:s3:::name.com/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AIDOFTHEUSER",
"ACCOUNTID"
]
}
}
}
]
}

Getting Access Denied when trying to upload to s3 Bucket

I am trying to upload an object to an AWS bucket using NodeJs (aws-sdk), but I am get access denied error.
The IAM user of which I am using accessKeyId and secretAccessKey also have been given access to the s3 bucket to which I am trying to upload.
Backend Code
const s3 = new AWS.S3({
accessKeyId: this.configService.get<string>('awsAccessKeyId'),
secretAccessKey: this.configService.get<string>('awsSecretAccessKey'),
params: {
Bucket: this.configService.get<string>('awsPublicBucketName'),
},
region: 'ap-south-1',
});
const uploadResult = await s3
.upload({
Bucket: this.configService.get<string>('awsPublicBucketName'),
Body: dataBuffer,
Key: `${folder}/${uuid()}-${filename}`,
})
.promise();
Bucket Policy
{
"Version": "2012-10-17",
"Id": "PolicyXXXXXXXXX",
"Statement": [
{
"Sid": "StmtXXXXXXXXXXXXXX",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::some-random-bucket"
},
{
"Sid": "StmtXXXXXXXXXXX",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXX:user/some-random-user"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::some-random-bucket"
}
]
}
You have an explicit deny statement, denying anyone from doing anything S3-related on some-random-bucket.
This will override any allow statements in the policy, according to the official IAM policy evaluation logic.
You can do any of the following:
Remove the deny statement from the policy
Modify the deny statement & use NotPrincipal to exclude some-random-user from the deny statement
Modify the deny statement & use the aws:PrincipalArn condition key with the ArnNotEquals condition operator to exclude some-random-user from the deny statement i.e.
{
"Version": "2012-10-17",
"Id": "PolicyXXXXXXXXX",
"Statement": [
{
"Sid": "StmtXXXXXXXXXXXXXX",
"Effect": "Deny",
"Action": "s3:*",
"Principal": "*",
"Resource": "arn:aws:s3:::some-random-bucket",
"Condition": {
"ArnNotEquals": {
"aws:PrincipalArn": "arn:aws:iam::XXXXXXXXXX:user/some-random-user"
}
}
},
{
"Sid": "StmtXXXXXXXXXXX",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXX:user/some-random-user"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::some-random-bucket"
}
]
}

Terraform v0.11 efs access permission denied

just want to ask if this has been a known issue on Terraform v0.11, I'm trying to mount efs to lambda however it seems being blocked on the part of querying the efs access point.
data.aws_efs_access_point.pogi: data.aws_efs_access_point.pogi: Error reading EFS access point : AccessDeniedException:
status code: 403, request id: 123k23s-1434-4421-as4ds-asd021390asdjj
my tf code below:
data "aws_efs_access_point" "pogi" {
access_point_id = "fsap-p0gigwap0h"
}
resource "aws_lambda_function" "pogi_function" {
function_name = "pogi-na-gwapo-pa"
...
file_system_config {
arn = "${data.aws_efs_access_point.pogi.arn}"
local_mount_path = "/mnt/pogi-mo"
}
}
NOTE: My tf code above is working when data source part is commented and arn value is hard coded
I'm using this IAM Role to deploy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt143441432",
"Action": [
"lambda:AddPermission",
"lambda:GetFunction",
"lambda:ListAliases",
"lambda:TagResource",
"lambda:UntagResource",
"lambda:UpdateFunctionConfiguration"
],
"Effect": "Allow",
"Resource": "arn:aws:lambda:us-east-1:1234567898765:function:pogi-*"
},
{
"Sid": "Stmt143441432",
"Action": [
"elasticfilesystem:Describe*",
"elasticfilesystem:List*"
],
"Effect": "Allow",
"Resource": "arn:aws:elasticfilesystem:us-east-1:1234567898765:file-system/*"
}
]
}

Creating an aws_api_gateway_account resource returns AccessDeniedException

In my terraform script I have the following resource -
resource "aws_api_gateway_account" "demo" {
cloudwatch_role_arn = var.apigw_cloudwatch_role_arn
}
In the Apply stage, I see the following error -
2020/09/21 20:20:48 [ERROR] <root>: eval: *terraform.EvalApplyPost, err: Updating API Gateway Account failed: AccessDeniedException:
status code: 403, request id: abb0662e-ead2-4d95-b987-7d889088a5ef
Is there a specific permission that needs to be attached to the role in order to get rid of this error?
Ran into the same problem as #bdev03, took me 2 days to identify the missing permission is "iam:PassRole", be so good if terraform is able to point that out, hope this helps.
Since neither this thread (so far) nor the official documentation is doing a very good job at solving this problem... The minimal policies required for this action are:
{
"Sid": "AllowPassingTheRoleToApiGateway",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": ["apigateway.amazonaws.com"]
}
}
}
{
"Sid": "AllowAPIGatewayUpdate",
"Effect": "Allow",
"Action": [
"apigateway:UpdateRestApiPolicy",
"apigateway:PATCH",
"apigateway:GET"
],
"Resource": "*"
}
I haven't tested, but I believe the role needs what's shown below. See more context at the source: "To enable CloudWatch Logs" section at https://docs.aws.amazon.com/apigateway/latest/developerguide/stages.html
For common application scenarios, the IAM role could attach the
managed policy of AmazonAPIGatewayPushToCloudWatchLogs, which contains
the following access policy statement:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "*"
}
] }
The IAM role must also contain the following trust relationship
statement:
{ "Version": "2012-10-17", "Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
} ] }

Folder Specific IAM Permissions for boto3 S3 API Calls

So I have a user whose IAM permissions are set to the following. It is meant to only allow them Create/Delete/List/etc. objects in the "Target_Folder/" for the bucket.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt123456789",
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::bucket/Target_Folder/*"
]
}
]
}
Using boto3, I embed the relevant aws_access_key_id and aws_secret_access_key in the config. After doing this, I find I am unable to preform any actions within the "/Target_Folder/" such as:
import boto3
import boto.s3.transfer
#Need to manually import S3Transfer() for some reason.
from boto.s3.transfer import S3Transfer
bucket = 'bucket'
prefix = 'Test_Folder/'
client = boto3.client(s3)
#Attempt to print objects under the Target_Folder
response = client.list_objects(Bucket = bucket, Prefix = prefix)
for file in response['Contents']:
print(file['key'])
#Attempt to upload file
transfer = S3Transfer(client)
transfer.upload_file('C:/filepath/file', bucket, prefix)
Ultimately, no matter what approach, I receive a "botocore.exceptions.ClientError: An error occured (SignatureDoesNotMatch)....". Conversely, if I use a key/secret_key pair with much more open bucket permissions, I have no issues interacting with the API.
Apologies if this has been answered or clarified in another thread, I could not find any good ones while searching.
First, the s3 bucket bucket should exist.
You need to assign s3:ListBucket permission on the s3 bucket, then you can give the object access permission in this bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Action":[
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource":"arn:aws:s3:::bucket"
},
{
"Sid": "Stmt123456789",
"Effect": "Allow",
"Action": [
"s3:CreateBucket", # and this should be removed.
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::bucket/Target_Folder/*"
]
}
]
}

Resources