0
votes

I'm starting a small project with AWS CDK. I have created a bucket with CDK.

this.myBucket = new s3.Bucket(this,'my-first-bucket',{
  removalPolicy: cdk.RemovalPolicy.DESTROY
});

When I deploy this using cdk deploy, CloudFormation creates a bucket using a generated bucket name, like mystack-myfirstbucket786ee605-1q912cjgtpj27.

Now, I start writing a lambda function, whose job will entail writing to this bucket. I pass the bucketName to the lambda by adding it to the lambda's environment variable.

this.myLambdaFunction = new lambda.Function(this, "my-function",{
  code: lambda.Code.fromAsset('lambda'),
  handler: 'myFunction.handler',
  runtime:  lambda.Runtime.NODEJS_14_X,
  memorySize: 256,
  timeout: cdk.Duration.seconds(60)
});

this.myLambdaFunction.addEnvironment('bucket', this.myBucket.bucketName );

When I run the lambda locally, as I iterate on developing it, if I inspect the process.env.bucket in my lambda, I see that it has a different generated bucket name i.e.myfirstbucket786ee605 that is different that the bucket that CloudFormation created. This prevents my lambda from writing to that bucket while I develop locally.

How am I supposed to maintain the CloudFormation state in between my local and AWS environment as I develop?

1

1 Answers

2
votes

In your lambda you can do this

this.myLambdaFunction = new lambda.Function(this, "my-function",{
  code: lambda.Code.fromAsset('lambda'),
  handler: 'myFunction.handler',
  runtime:  lambda.Runtime.NODEJS_14_X,
  memorySize: 256,
  environment: {
    s3BucketName: this.myBucket.bucketName
  }
  timeout: cdk.Duration.seconds(60)
});

Then in your code that runs in the lambda you can get the bucket name as:

export const handler = async (event) => {
   let s3BucketName = process.env.s3BucketName;
}

That should get you the environment name you need.

Side note: If you go to AWS lambda page and navigate to your lambda you can go to configuration and see what environment variables were saved.

Update 2 Another way you can do it is modify your stack that creates the bucket store the bucket name in SSM StringParameter such as:

new ssm.StringParameter(this, 'My Bucket Name', {
  parameterName: 'My Bucket Name',
  stringValue:  this.myBucket.bucketName
});

Then in the stack that you create your lambda in you can get your bucket name and set the variable that way

let s3BucketName = ssm.StringParameter.valueForStringParameter(this, 'My Bucket Name');

this.myLambdaFunction = new lambda.Function(this, "my-function",{
  code: lambda.Code.fromAsset('lambda'),
  handler: 'myFunction.handler',
  runtime:  lambda.Runtime.NODEJS_14_X,
  memorySize: 256,
  environment: {
    s3BucketName: s3BucketName
  }
  timeout: cdk.Duration.seconds(60)
});

Another thing you can try is to fetch the ssm value in the lambda using aws-sdk: import * as AWS from 'aws-sdk'; export const handler = async (event) => {

 let ssm = new AWS.SSM({
   region: <region>,
   accessKeyId: '',
   secretAccessKey: ''
 });

  var params = {
    Name: 'My Bucket Name',
    WithDecryption: true || false
  }
    
  let s3Bucket = '';
  await ssm.getParameter(params).promise().then((data) => {
    s3Bucket = data.Parameter.Value
  });
}