I am working with a problem that has a few other similar solutions posted on stackoverflow
(1) Argument of type 'this' is not assignable to parameter of type 'Construct' in AWS CDK
(2) AWS CDK, typescript - Argument of type 'this' is not assignable to parameter of type 'Construct'
I tried making all my aws library versions match per this advice:
"This might happen because you are using CDK module with a different version than the CDK core library. CDK updates very often so it's a quite common error.
For fixing this you need to update all the cdk packages to the same version."
The advice is repeated here in different words, so i did all that:
Delete node_modules folder
Delete package-lock.json
Ensure all dependencies in package.json are using same version.
Remove carrot ^ symbol before dependencies
npm install
Now my package json is this:
{
"name": "cdk-eb-infra",
"version": "0.1.0",
"bin": {
"cdk-eb-infra": "bin/cdk-eb-infra.js"
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"test": "jest",
"cdk": "cdk"
},
"devDependencies": {
"@types/jest": "^29.2.4",
"@types/node": "18.11.15",
"aws-cdk": "2.59.0",
"jest": "^29.3.1",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typescript": "~4.9.4"
},
"dependencies": {
"@aws-cdk/aws-elasticbeanstalk": "1.187.0", // note identical versions
"@aws-cdk/aws-iam": "1.187.0", // note identical versions
"@aws-cdk/aws-s3-assets": "1.187.0", // note identical versions
"@aws-cdk/core": "1.187.0", // note identical versions
"aws-cdk-lib": "2.59.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
}
Now I try to run cdk deploy
and I get
lib/cdk-eb-infra-stack.ts:20:57 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'Construct'.
Type 'CdkEbInfraStack' is missing the following properties from type 'Construct': onValidate, onPrepare, onSynthesize, validate, and 2 more.
20 const app = new elasticbeanstalk.CfnApplication(this, "Application", {
~~~~
lib/cdk-eb-infra-stack.ts:25:76 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'Construct'.
25 const appVersionProps = new elasticbeanstalk.CfnApplicationVersion(this, "AppVersion", {
~~~~
lib/cdk-eb-infra-stack.ts:37:37 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'Construct'.
37 const myRole = new iam.Role(this, `${appName}-aws-elasticbeanstalk-ec2-role`, {
~~~~
lib/cdk-eb-infra-stack.ts:46:60 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'Construct'.
46 const instanceProfile = new iam.CfnInstanceProfile(this, myProfileName, {
What is the solution?
edit: Sharing the (sorry, long) code of my cdk-eb-infra-stack.ts
file in the /lib
folder:
import * as cdk from "aws-cdk-lib";
import iam = require("@aws-cdk/aws-iam");
import elasticbeanstalk = require("@aws-cdk/aws-elasticbeanstalk");
import s3assets = require("@aws-cdk/aws-s3-assets");
import { Construct } from "constructs";
// 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`,
});
// Create a ElasticBeanStalk app.
const appName = "MyWebApp";
const app = new elasticbeanstalk.CfnApplication(this, "Application", {
applicationName: appName,
});
// Create an app version from the S3 asset defined earlier
const appVersionProps = new elasticbeanstalk.CfnApplicationVersion(this, "AppVersion", {
applicationName: appName,
sourceBundle: {
s3Bucket: webAppZipArchive.s3BucketName,
s3Key: webAppZipArchive.s3ObjectKey,
},
});
// Make sure that Elastic Beanstalk app exists before creating an app version
appVersionProps.addDependsOn(app);
// Create role and instance profile
const myRole = new iam.Role(this, `${appName}-aws-elasticbeanstalk-ec2-role`, {
assumedBy: 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],
});
}
}
I did exclusively copy-paste from Module 2: Create Infrastructure using AWS CDK
CodePudding user response:
You are mixing V1 and V2 dependencies. Remove the V1 dependencies, that is, the packages in your package.json
with version 1.187.0
. Import service-specific packages from aws-cdk-lib
:
import {
aws_iam as iam,
aws_elasticbeanstalk as elasticbeanstalk,
aws_s3_assets as s3_assets,
} from "aws-cdk-lib";
In V2, only the non-stable "alpha" modules are in separate packages.
CodePudding user response:
It appears you are mixing CDKv1 and CDKv2 packages.
This would fall under Ensure all dependencies in package.json are using same version.
Change
"dependencies": {
"@aws-cdk/aws-elasticbeanstalk": "1.187.0", // note identical versions
"@aws-cdk/aws-iam": "1.187.0", // note identical versions
"@aws-cdk/aws-s3-assets": "1.187.0", // note identical versions
"@aws-cdk/core": "1.187.0", // note identical versions
"aws-cdk-lib": "2.59.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
to
"dependencies": {
"aws-cdk-lib": "2.59.0", // CDKv2
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
Edit: per the answer from @fedonev
Update your imports like so:
import {
aws_iam as iam,
aws_elasticbeanstalk as elasticbeanstalk,
aws_s3_assets as s3_assets,
} from "aws-cdk-lib";
In V2, only the non-stable "alpha" modules are in separate packages.
Pardon me, I am new to citing on StackOverflow. Edit if there is a better way to attribute @fedonev
CodePudding user response:
Both Fedonev and Jacob Greenbow posted helpful responses. I was able to make the following changes and get it working:
import { Stack, StackProps, aws_iam as iam, aws_elasticbeanstalk as elasticbeanstalk, aws_s3_assets as s3_assets } from "aws-cdk-lib";
import { Construct } from "constructs";
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class CdkEbInfraStack extends Stack {
constructor(scope: Construct, id: string, props?: 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 s3_assets.Asset(this, "WebAppZip", {
path: `${__dirname}/../app.zip`,
});
// Create a ElasticBeanStalk app.
const appName = "MyWebApp";
const app = new elasticbeanstalk.CfnApplication(this, "Application", {
applicationName: appName,
});
// Create an app version from the S3 asset defined earlier
const appVersionProps = new elasticbeanstalk.CfnApplicationVersion(this, "AppVersion", {
applicationName: appName,
sourceBundle: {
s3Bucket: webAppZipArchive.s3BucketName,
s3Key: webAppZipArchive.s3ObjectKey,
},
});
// Make sure that Elastic Beanstalk app exists before creating an app version
appVersionProps.addDependsOn(app);
// Create role and instance profile
const myRole = new iam.Role(this, `${appName}-aws-elasticbeanstalk-ec2-role`, {
assumedBy: 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],
});
}
}
Note that the Stack
and StackProps
had to be imported too to avoid breaking the rest of amazon's example.