In my cdk-eb-infra-stack.ts file, I’m getting an error when passing this
as parameter into CDK methods.
Here’s what my file looks like:
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import s3assets = require("@aws-cdk/aws-s3-assets");
import elasticbeanstalk = require("@aws-cdk/aws-elasticbeanstalk");
import iam = require("@aws-cdk/aws-iam");
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class CdkEbInfraStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
// Construct an S3 asset from the ZIP located from directory up
const webAppZipArchive = new s3assets.Asset(this, "WebAppZip", {
path: `${__dirname}/../app.zip`,
});
const appName = "REDACTED";
const app = new elasticbeanstalk.CfnApplication(this, "Application", {
applicationName: appName,
});
const appVersionProps = new elasticbeanstalk.CfnApplicationVersion(
this,
"AppVersion",
{
applicationName: appName,
sourceBundle: {
s3Bucket: webAppZipArchive.s3BucketName,
s3Key: webAppZipArchive.s3ObjectKey,
},
}
);
appVersionProps.addDependsOn(app);
// Create role and instance profile
const myRole = new iam.Role(
this,
`${appName}-aws-elasticbeanstalk-ec2-role`,
{
assumeBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
}
);
const managedPolicy = iam.ManagedPolicy.fromAwsManagedPolicyName(
"AWSElasticBeanstalkWebTier"
);
myRole.addManagedPolicy(managedPolicy);
const myProfileName = `${appName}-InstanceProfile`;
const instanceProfile = new iam.CfnInstanceProfile(this, myProfileName, {
instanceProfileName: myProfileName,
roles: [myRole.roleName],
});
const optionSettingProperties: elasticbeanstalk.CfnEnvironment.OptionSettingProperty[] =
[
{
namespace: "aws:autoscaling:launchconfiguration",
optionName: "IamInstanceProfile",
value: myProfileName,
},
{
namespace: "aws:autoscaling:asg",
optionName: "MinSize",
value: "1",
},
{
namespace: "aws:autoscaling:asg",
optionName: "MaxSize",
value: "1",
},
{
namespace: "aws:ec2:instances",
optionName: "InstanceTypes",
value: "t2.micro",
},
];
// Create an Elastic Beanstalk environment to run the application
const elbEnv = new elasticbeanstalk.CfnEnvironment(this, "Environment", {
environmentName: "REDACTED",
applicationName: app.applicationName || appName,
solutionStackName: "64bit Amazon Linux 2 v5.5.6 running Node.js 16",
optionSettings: optionSettingProperties,
versionLabel: appVersionProps.ref,
});
// example resource
// const queue = new sqs.Queue(this, 'CdkEbInfraQueue', {
// visibilityTimeout: cdk.Duration.seconds(300)
// });
}
}
I know this problem occurs due to versions of aws-cdk packages differing, but I’ve implemented all the solutions I could find and I unfortunately haven’t been able to resolve it.
My dependencies in my package.json file look like this;
"dependencies": {
"@aws-cdk/aws-elasticbeanstalk": "^1.172.0",
"@aws-cdk/aws-iam": "^1.172.0",
"@aws-cdk/aws-s3-assets": "^1.172.0",
"@aws-cdk/core": "^1.172.0",
"aws-cdk-lib": "2.41.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
And my globally installed cdk looks like this:
[email protected]
Before, I had the global cdk installed at the latest version. I thought that it being a different version to the @aws-cdk packages might be causing the issue, so I downloaded it at the same version as the packages. It doesn’t seem to have solved the problem though.
These are all the packages installed in my cdk-eb-infra project directory:
├── @aws-cdk/[email protected]
├── @aws-cdk/[email protected]
├── @aws-cdk/[email protected]
├── @aws-cdk/[email protected]
├── @types/[email protected]
├── @types/[email protected]
├── @types/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
What is it that I’m missing here?
2
Answers
Pretty ridiculous that they haven't updated the documentation for this, but fortunately managed to resolve the problem. The solution had nothing to do with library version mismatch, but rather to do with the fact that importing individual libraries related to different AWS services is now legacy. AWS CDK v2 now stores all packages in aws-cdk-lib. When importing, import the individual dependencies from it like so (using s3 assets as an example):
You can read more about it here.
The guide OP linked to is outdated since AWS updated aws-cdk-lib to version 2 to include all the individual functions for AWS core services.
these three lines (and corresponding code calling these libraries) are the problem:
Replace them with this line:
import * as cdk from 'aws-cdk-lib';
What this does is import all the classes from the entire library (maybe overkill, but it’s a beginner tutorial right?) So you automatically get every class from iam, elasticbeanstalk and s3assets.
Later on in the code, though, you’ll have to rearrange slightly, for example line 14:
s3assets will no longer work since we don’t declare that up in the imports anymore with the require directive. (if you want this to work as the tutorial shows you can individually import aws-cdk classes using the info at "work with cdk typescript aws docs" )
To fix this we need to specifically call the exact scope of the relevant construct – aws_s3_assets.Asset (see below):
You’ll want to make this adjustment for every time you try to call one of your functions from your three outdated imports (iam, elasticbeanstalk, s3assets).
I used ConstructsHub to look up the proper submodule names to update the code (make sure you change to latest version since that link might get stale quickly.)
You will need to
rm -rf node_modules
,rm -rf package-lock.json
andnpm install
to update your packages, then runnpm build run
to update the typescript.It should compile without error if you caught all the spots where the v2 functions changed.
Lastly, I had to update the Environment Settings (last block of code) with a more recent
SolutionStackName
The current list can be found using
aws elasticbeanstalk list-available-solution-stacks
Pick your current node version. You can follow the rest of the tut to get deployed!
Hope this helps someone else going through this!