AWS CDK сообщает, что аргумент типа «это» не может быть назначен параметру типа «Конструкция»

Я работаю над проблемой, для которой есть несколько других подобных решений, опубликованных в stackoverflow.

(1) Аргумент типа this нельзя назначить параметру типа Construct в AWS CDK

(2) AWS CDK, typescript — Аргумент типа «это» нельзя присвоить параметру типа «Конструкция»

Я попытался сделать так, чтобы все версии моей библиотеки aws совпадали в соответствии с этим советом:

«Это может произойти из-за того, что вы используете модуль CDK с версией, отличной от основной библиотеки CDK. CDK очень часто обновляется, поэтому это довольно распространенная ошибка.

Чтобы исправить это, вам нужно обновить все пакеты cdk до одной версии».

Совет повторяется здесь другими словами, поэтому я сделал все так:

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

Теперь мой пакет json таков:

{
    "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"
    }
}

Сейчас пытаюсь бежать cdk deploy и получаю

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, {

Каково решение?

Edit: Делюсь (извините, длинным) кодом моего cdk-eb-infra-stack.ts файла в /lib папке:

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],
        });
    }
}

Я сделал исключительно копипасту из Модуля 2: Создание инфраструктуры с помощью AWS CDK

Не могли бы вы поделиться соответствующими частями вашего фактического стека CDK?

lxg 10.01.2023 19:09
Принципы SOLID в JavaScript с примерами
Принципы SOLID в JavaScript с примерами
Принцип единой ответственности подразумевает то, что:
Типы привязки данных в Angular
Типы привязки данных в Angular
Привязка данных автоматически поддерживает страницу в актуальном состоянии на основе состояния вашего приложения. Вы используете привязку данных,...
3 паттерна TypeScript, которые я использую в своей повседневной работе
3 паттерна TypeScript, которые я использую в своей повседневной работе
В TypeScript 2.0 в язык был добавлен модификатор readonly.
Мифический Angular - Миф Angular: стили компонентов
Мифический Angular - Миф Angular: стили компонентов
Это очень короткая и интересная для меня тема. В Angular каждый компонент может иметь свои собственные прикрепленные стили. Стили могут находиться в...
Подсказка RxJS [filter, skipWhile]
Подсказка RxJS [filter, skipWhile]
Эта подсказка описывает разницу между операторами filter и skipWhile из библиотеки RxJS .
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
0
1
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Похоже, вы смешиваете пакеты CDKv1 и CDKv2.

Документация по миграции CDKv2

Это подпадает под Ensure all dependencies in package.json are using same version.

Изменять

"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"
}

К

"dependencies": {
    "aws-cdk-lib": "2.59.0", // CDKv2
    "constructs": "^10.0.0",
    "source-map-support": "^0.5.21"
}

Обновлено: согласно ответу @fedonev

Обновите свой импорт следующим образом:

import {
  aws_iam as iam,
  aws_elasticbeanstalk as elasticbeanstalk,
  aws_s3_assets as s3_assets,
} from "aws-cdk-lib";

В V2 только нестабильные "альфа" модули находятся в отдельных пакетах.

Извините, я новичок в цитировании StackOverflow. Отредактируйте, если есть лучший способ атрибутировать @fedonev

Ответ принят как подходящий

Вы смешиваете зависимости V1 и V2. Удалите зависимости V1, то есть пакеты в вашем package.json с версией 1.187.0. Импорт пакетов для конкретных служб из aws-cdk-lib:

import {
  aws_iam as iam,
  aws_elasticbeanstalk as elasticbeanstalk,
  aws_s3_assets as s3_assets,
} from "aws-cdk-lib";

В V2 только нестабильные "альфа" модули находятся в отдельных пакетах.

Я думаю, это сработало, подожди, дай мне проверить. edit: Да, cdk deploy теперь говорит: «Сбой создания ресурсов: Ошибка: Сбой создания ресурсов: Ошибка: Невозможно разрешить использование учетной записи AWS. Он должен быть настроен либо при определении стека CDK, либо через среду, что означает, что ваше решение сработало. Спасибо

plutownium 10.01.2023 19:42

И Федонев, и Джейкоб Гринбоу оставили полезные ответы. Я смог внести следующие изменения и заставить его работать:

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],
        });
    }
}

Обратите внимание, что Stack и StackProps тоже нужно было импортировать, чтобы не сломать остальную часть примера Amazon.

Другие вопросы по теме