Search code examples
amazon-s3aws-cdk

How to get the uploaded file names using AWS CDK BucketDeployment?


Background context:

I am using AWS CDK to create a S3 bucket and upload a file locally, So Inside the BucketA, I have a Object with keytext1.txt.

I am trying to use CfnOutput to output the Object I upload in the CDK. It should be text1.txt, Is there a way to retrieve the object key i just upload?

Here is how I create bucket and upload text1.txt object:

const bucketA = new Bucket(this, 'S3Bucket', {
  accessControl: BucketAccessControl.BUCKET_OWNER_FULL_CONTROL,
  blockPublicAccess: BlockPublicAccess.BLOCK_ACLS,
  bucketName: `bucketA`,
  enforceSSL: true,
  removalPolicy: RemovalPolicy.DESTROY
});

const uploadObject = new s3Deployment.BucketDeployment(
  this,
  `text1`,
  {
    sources: [s3Deployment.Source.asset(VALID_METADATA_PATH)],
    destinationBucket: bucketA,
    retainOnDelete: false,
    role: deploymentRole
  }
);

Here is what I tried:

new CfnOutput(this, 'fileKey', {
    value: Fn.select(0, uploadObject.objectKeys)
});

However, when I check the output, it does not output the value I want,(text1.txt), rather it output something like:

this:cdk.out/asset.{315...a lot of numbers }.zip

When I inspect this asset.{315...a lot of numbers } locally in the cdk.out folder, I could see the text1.txt file inside asset.{315...a lot of numbers }


Solution

  • Update:

    When using aws_s3_deployment.BucketDeployment there are 3 options how to pass source assets:

    1. Source.asset and path to .zip file that contains all assets you want to upload.
    2. Source.asset and path to directory with assets you want to upload.
    3. Source.data/Source.jsonData/Source.yamlData will require to provide content of a file to upload.

    All options except #1 will be packed as .zip file eventually and sent to S3 where they get unpacked back. That's why you always see zip files in uploadObject.objectKeys. Here is what documentation is saying:

    This can be useful when using BucketDeployment with extract set to false and you need to reference the object key that resides in the bucket for that zip source file somewhere else in your CDK application, such as in a CFN output.

    As you can see it will give you zipped source assets file name. You can try just read local file system in order to get desired output:

    fs.readdir(VALID_METADATA_PATH, {withFileTypes: true}, (err, files) => {
       files.forEach((file) => {
          new CfnOutput(this, `fileKey${i++}`, {
             value: file.name
          });
       });
    });
    

    Try running this code, it seems that variable name is wrong:

    // Output the key of the uploaded object
    new CfnOutput(this, 'fileKey', {
      value: Fn.select(0, uploadObject.objectKeys)
    });