aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.51k stars 3.85k forks source link

aws_s3: Implement requester pays #31031

Open giusedroid opened 1 month ago

giusedroid commented 1 month ago

Describe the feature

Enable S3 requester pays

Enabling s3 requester pays as a property of BucketProperty would help customers managing the state of their payment options directly from code.

    const bucket = new s3.Bucket(this, 'RequesterPaysBucket', {
      //requester pays
      paymentRequests: true, // or something like that
    });

Use Case

As of now, I could not find a way to declaratively set this option on a bucket.

Proposed Solution

there's no CloudFormation equivalent option on AWS::S3::Bucket, so this may not be an easy fix. Here's a link to the docs where they show how to implement this via an HTTP request.

Potentially this could be implemented as a custom resource depending on the bucket

// lambda/set-requyester-pays.js
const { S3Client, PutBucketRequestPaymentCommand } = require('@aws-sdk/client-s3');

exports.handler = async (event) => {
    const bucketName = event.ResourceProperties.BucketName;

    if (!bucketName) {
        return {
            status: 'FAILED',
            reason: 'Bucket name is required',
        };
    }

    const s3Client = new S3Client({ region: process.env.AWS_REGION });

    const params = {
        Bucket: bucketName,
        RequestPaymentConfiguration: {
            Payer: 'Requester'
        }
    };

    try {
        await s3Client.send(new PutBucketRequestPaymentCommand(params));
        return {
            status: 'SUCCESS',
            reason: 'Requester pays enabled successfully',
        };
    } catch (error) {
        return {
            status: 'FAILED',
            reason: `Error enabling requester pays: ${error.message}`,
        };
    }
};
// within a stack
// Custom Resource Lambda to set requester pays
    const setRequesterPaysLambda = new lambda.Function(this, 'SetRequesterPaysLambda', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'set-requester-pays.handler',
      code: lambda.Code.fromAsset(path.join(__dirname, '../lambda'))
    });

    // Custom Resource to trigger the lambda
    const customResourceProvider = new Provider(this, 'CustomResourceProvider', {
      onEventHandler: setRequesterPaysLambda,
    });

    new CustomResource(this, 'SetRequesterPaysCustomResource', {
      serviceToken: customResourceProvider.serviceToken,
      properties: {
        BucketName: bucket.bucketName,
      },
    });

Other Information

No response

Acknowledgements

CDK version used

2.151.0

Environment details (OS name and version, etc.)

mac os

giusedroid commented 1 month ago

with reference to: https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/123

giusedroid commented 1 month ago

this solution is even better: https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/123#issuecomment-932532908

ashishdhingra commented 1 month ago

@giusedroid Good morning. As rightly pointed out by you, there is an open issue https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/123 in CloudFormation repository. The constructs in CDK are limited by the functionality provided by CloudFormation. Once CloudFormation specification supports RequesterPays property, it would be available as part of CDK CfnBucket L1 construct. The workaround to use custom resource as suggested in https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/123#issuecomment-932532908 is the way to go forward as of now.

Thanks, Ashish