public async migrate()

in packages/aws-cdk/lib/cli/cdk-toolkit.ts [1125:1211]


  public async migrate(options: MigrateOptions): Promise<void> {
    warning('This command is an experimental feature.');
    const language = options.language?.toLowerCase() ?? 'typescript';
    const environment = setEnvironment(options.account, options.region);
    let generateTemplateOutput: GenerateTemplateOutput | undefined;
    let cfn: CfnTemplateGeneratorProvider | undefined;
    let templateToDelete: string | undefined;

    try {
      // if neither fromPath nor fromStack is provided, generate a template using cloudformation
      const scanType = parseSourceOptions(options.fromPath, options.fromStack, options.stackName).source;
      if (scanType == TemplateSourceOptions.SCAN) {
        generateTemplateOutput = await generateTemplate({
          stackName: options.stackName,
          filters: options.filter,
          fromScan: options.fromScan,
          sdkProvider: this.props.sdkProvider,
          environment: environment,
        });
        templateToDelete = generateTemplateOutput.templateId;
      } else if (scanType == TemplateSourceOptions.PATH) {
        const templateBody = readFromPath(options.fromPath!);

        const parsedTemplate = deserializeStructure(templateBody);
        const templateId = parsedTemplate.Metadata?.TemplateId?.toString();
        if (templateId) {
          // if we have a template id, we can call describe generated template to get the resource identifiers
          // resource metadata, and template source to generate the template
          cfn = new CfnTemplateGeneratorProvider(await buildCfnClient(this.props.sdkProvider, environment));
          const generatedTemplateSummary = await cfn.describeGeneratedTemplate(templateId);
          generateTemplateOutput = buildGenertedTemplateOutput(
            generatedTemplateSummary,
            templateBody,
            generatedTemplateSummary.GeneratedTemplateId!,
          );
        } else {
          generateTemplateOutput = {
            migrateJson: {
              templateBody: templateBody,
              source: 'localfile',
            },
          };
        }
      } else if (scanType == TemplateSourceOptions.STACK) {
        const template = await readFromStack(options.stackName, this.props.sdkProvider, environment);
        if (!template) {
          throw new ToolkitError(`No template found for stack-name: ${options.stackName}`);
        }
        generateTemplateOutput = {
          migrateJson: {
            templateBody: template,
            source: options.stackName,
          },
        };
      } else {
        // We shouldn't ever get here, but just in case.
        throw new ToolkitError(`Invalid source option provided: ${scanType}`);
      }
      const stack = generateStack(generateTemplateOutput.migrateJson.templateBody, options.stackName, language);
      success(' ⏳  Generating CDK app for %s...', chalk.blue(options.stackName));
      await generateCdkApp(options.stackName, stack!, language, options.outputPath, options.compress);
      if (generateTemplateOutput) {
        writeMigrateJsonFile(options.outputPath, options.stackName, generateTemplateOutput.migrateJson);
      }
      if (isThereAWarning(generateTemplateOutput)) {
        warning(
          ' ⚠️  Some resources could not be migrated completely. Please review the README.md file for more information.',
        );
        appendWarningsToReadme(
          `${path.join(options.outputPath ?? process.cwd(), options.stackName)}/README.md`,
          generateTemplateOutput.resources!,
        );
      }
    } catch (e) {
      error(' ❌  Migrate failed for `%s`: %s', options.stackName, (e as Error).message);
      throw e;
    } finally {
      if (templateToDelete) {
        if (!cfn) {
          cfn = new CfnTemplateGeneratorProvider(await buildCfnClient(this.props.sdkProvider, environment));
        }
        if (!process.env.MIGRATE_INTEG_TEST) {
          await cfn.deleteGeneratedTemplate(templateToDelete);
        }
      }
    }
  }