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.6k stars 3.9k forks source link

CloudFormation Parameters are missing a value #26974

Open marhuo opened 1 year ago

marhuo commented 1 year ago

Describe the bug

Hi I'm fairly new to CDK so bear with me. I'm trying to implement codepipeline that deploys to lambda according to the following example in documentation https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_codepipeline_actions-readme.html in section "Lambda deployed through CodePipeline". I had version 2.87.0 of cdk and I got it to work couple of times, most of the times it failed with error "The following CloudFormation Parameters are missing a value". So I updated everything now I can't get it to work at all, same error. Rather than providing my actual source code, I translated the example to C#. It produces the same error, but is incomplete in otherways. I tried different ways of passing cloudformation parameters but I get the same error. I apologize if this is a false report. If there is any other information I can give, please ask

Expected Behavior

Deployment to pass

Current Behavior

❌ LambdaStack failed: Error: The following CloudFormation Parameters are missing a value: LambdaLambdaSourceBucketNameParameter159473FC, LambdaLambdaSourceObjectKeyParameter06573F1D at new ParameterValues (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:433:19822) at _TemplateParameters.updateExisting (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:433:19079) at deployStack (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:437:79232) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.deployStack2 [as deployStack] (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:446:153718) at async C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:446:137166

❌ Deployment failed: Error: The following CloudFormation Parameters are missing a value: LambdaLambdaSourceBucketNameParameter159473FC, LambdaLambdaSourceObjectKeyParameter06573F1D at new ParameterValues (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:433:19822) at _TemplateParameters.updateExisting (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:433:19079) at deployStack (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:437:79232) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.deployStack2 [as deployStack] (C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:446:153718) at async C:\Users{my_name}\AppData\Roaming\nvm\v20.5.1\node_modules\aws-cdk\lib\index.js:446:137166

The following CloudFormation Parameters are missing a value: LambdaLambdaSourceBucketNameParameter159473FC, LambdaLambdaSourceObjectKeyParameter06573F1D

Reproduction Steps

 using Amazon.CDK;
 using Amazon.CDK.AWS.CodeBuild;
 using Amazon.CDK.AWS.CodeCommit;
 using Amazon.CDK.AWS.CodePipeline;
 using Amazon.CDK.AWS.CodePipeline.Actions;
 using Amazon.CDK.AWS.Lambda;

 var app = new App();
 var lambdaStack = new Stack(app, "LambdaStack");
 var lambdaCode = Amazon.CDK.AWS.Lambda.Code.FromCfnParameters();

 new Function(lambdaStack, "Lambda", new FunctionProps
 {
     Code = lambdaCode,
     Handler = "WeatherForecast.WebApi",
     Runtime = Runtime.DOTNET_6
 });

 var pipelineStack = new Stack(app, "PipelineStack");
 var pipeline = new Pipeline(pipelineStack, "Pipeline");

 // add the source code repository containing this code to your Pipeline,
 // and the source code of the Lambda Function, if they're separate
 var cdkSourceOutput = new Artifact_();
 var cdkSourceAction = new CodeCommitSourceAction(new CodeCommitSourceActionProps
 {
     Repository =  Repository.FromRepositoryName(pipelineStack, "CdkCodeRepo", "WeatherForecast"),
     ActionName = "CdkCode_Source",
     Output = cdkSourceOutput
 });

 var lambdaSourceOutput = new Artifact_();
 var lambdaSourceAction = new CodeCommitSourceAction(new CodeCommitSourceActionProps
 {
     Repository =  Repository.FromRepositoryName(pipelineStack, "LambdaCodeRepo", "WeatherForecast"),
     ActionName = "LambdaCode_Source",
     Output = lambdaSourceOutput
 });
 pipeline.AddStage(new StageOptions
 {
     StageName = "Source",
     Actions = new []{ cdkSourceAction, lambdaSourceAction }
 });
 // synthesize the Lambda CDK template, using CodeBuild
 // the below values are just examples, assuming your CDK code is in TypeScript/JavaScript -
 // adjust the build environment and/or commands accordingly
 var cdkBuildProject = new PipelineProject(pipelineStack, "CdkBuildProject", new PipelineProjectProps
 {
     BuildSpec = BuildSpec.FromSourceFilename("WeatherForecast.CdkV2/buildspec_cdk.yml"),
     Environment = new BuildEnvironment
     {
         BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5
     }
 });
 var cdkBuildOutput = new Artifact_();
 var cdkBuildAction = new CodeBuildAction(new CodeBuildActionProps
 {
     ActionName = "CDK_Build",
     Project = cdkBuildProject,
     Input = cdkSourceOutput,
     Outputs = new []{ cdkBuildOutput }
 });

 // build your Lambda code, using CodeBuild
 // again, this example assumes your Lambda is written in TypeScript/JavaScript -
 // make sure to adjust the build environment and/or commands if they don't match your specific situation
 var lambdaBuildProject = new PipelineProject(pipelineStack, "LambdaBuildProject", new PipelineProjectProps
 {
     BuildSpec = BuildSpec.FromSourceFilename("WeatherForecast.CdkV2/buildspec_lambda.yml"),
     Environment = new BuildEnvironment
     {
         BuildImage = LinuxBuildImage.AMAZON_LINUX_2_5
     }
 });
 var lambdaBuildOutput = new Artifact_();
 var lambdaBuildAction = new CodeBuildAction(new CodeBuildActionProps
 {
    ActionName = "Lambda_Build",
    Project = lambdaBuildProject,
    Input = lambdaSourceOutput,
    Outputs = new []{ lambdaBuildOutput }
 });
 pipeline.AddStage(new StageOptions
 {
     StageName = "Build",
     Actions = new []{ cdkBuildAction, lambdaBuildAction }
 });
 pipeline.AddStage(new StageOptions
 {
    StageName = "Deploy",
    Actions = new []{ 
        new CloudFormationCreateUpdateStackAction(new CloudFormationCreateUpdateStackActionProps
        {
            ActionName = "Lambda_CFN_Deploy",
            TemplatePath = cdkBuildOutput.AtPath("LambdaStack.template.json"),
            StackName = "LambdaStackDeployedName",
            AdminPermissions = true,
            ParameterOverrides = lambdaCode.Assign(lambdaBuildOutput.S3Location),
           ExtraInputs = new []{  lambdaBuildOutput }
        })
    }
 });
 app.Synth();

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.93.0 (build 724bd01)

Framework Version

net6.0

Node.js Version

v20.5.1

OS

Windows

Language

.NET

Language Version

10.0

Other information

No response

pahud commented 1 year ago

This sample actually comes from this integ testing https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-codepipeline-actions/test/integ.lambda-deployed-through-codepipeline.lit.ts and yes I got the same errors when I deploy that. We probably should fix that integ test.

7empestx commented 9 months ago

I understand that my example is in TypeScript while your question is related to .NET. I hope the following TypeScript code can still provide some assistance:

You should setup a lambda stack that looks something like this and define your CfnParameters as such


import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';

interface LambdaStackProps extends cdk.StackProps {
  stageName: string;
}

export class LambdaStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: LambdaStackProps) {
    super(scope, id, props);

    const bucketNameParam = new cdk.CfnParameter(this,'BucketNameParameter',  {
      type: 'String',
      description: 'The name of the S3 bucket to use for deployment',
      default: 'lambda-deployments',
    });
    const objectKeyParam = new cdk.CfnParameter(this, 'objectKeyParam', {
      type: 'String',
      description: 'The name of the S3 object to use for deployment',
      default: 'lambda.zip',
    });

    const lambdaCode = lambda.Code.fromCfnParameters({
      bucketNameParam: bucketNameParam,
      objectKeyParam: objectKeyParam,
    });

    new lambda.Function(this, 'Lambda', {
      code: lambdaCode,
      handler: 'index.handler',
      runtime: lambda.Runtime.NODEJS_LATEST,
    });
  }
}