export async function deploy()

in src/deployments/cdk/src/apps/phase-5.ts [45:256]


export async function deploy({ acceleratorConfig, accountStacks, accounts, context, outputs }: PhaseInput) {
  const { defaultRegion } = context;
  // Find the account buckets in the outputs
  const accountBuckets = defaults.AccountBucketOutput.getAccountBuckets({
    accounts,
    accountStacks,
    config: acceleratorConfig,
    outputs,
  });

  // Find the central bucket in the outputs
  const centralBucket = defaults.CentralBucketOutput.getBucket({
    accountStacks,
    config: acceleratorConfig,
    outputs,
  });

  const accountNames = acceleratorConfig
    .getMandatoryAccountConfigs()
    .map(([_, accountConfig]) => accountConfig['account-name']);

  const masterAccountKey = acceleratorConfig.getMandatoryAccountKey('master');
  const masterAccountId = getAccountId(accounts, masterAccountKey);
  if (!masterAccountId) {
    throw new Error(`Cannot find mandatory primary account ${masterAccountKey}`);
  }

  // TODO Move to deployments/mad/step-x.ts
  type UserSecrets = UserSecret[];
  for (const [accountKey, accountConfig] of acceleratorConfig.getMandatoryAccountConfigs()) {
    const madConfig = accountConfig.deployments?.mad;
    if (!madConfig || !madConfig.deploy) {
      continue;
    }

    const madAutoScalingRoleOutputs = StructuredOutput.fromOutputs(outputs, {
      accountKey,
      type: MadAutoScalingRoleOutputType,
    });
    if (madAutoScalingRoleOutputs.length !== 1) {
      console.warn(`Cannot find required service-linked auto scaling role in account "${accountKey}"`);
      continue;
    }
    const madAutoScalingRoleOutput = madAutoScalingRoleOutputs[0];

    const stack = accountStacks.tryGetOrCreateAccountStack(accountKey, madConfig.region);
    if (!stack) {
      console.warn(`Cannot find account stack ${accountKey}`);
      continue;
    }

    const keyPair = new AcceleratorKeypair(stack, 'RDGWEc2KeyPair', {
      name: 'rdgw-key-pair',
    });

    const userSecrets: UserSecrets = [];
    for (const adUser of madConfig['ad-users']) {
      const passwordSecretArn = getMadUserPasswordSecretArn({
        acceleratorPrefix: context.acceleratorPrefix,
        accountKey,
        secretAccountId: masterAccountId,
        userId: adUser.user,
      });
      userSecrets.push({ user: adUser.user, passwordSecretArn });
    }

    const madAutoScalingImageIdOutput = ImageIdOutputFinder.tryFindOneByName({
      outputs,
      accountKey,
      imageKey: 'MadAutoScalingImageId',
    });
    if (!madAutoScalingImageIdOutput) {
      console.warn(`Cannot find required auto scaling Image Id in account "${accountKey}"`);
      continue;
    }

    const rdgwScriptsOutput: RdgwArtifactsOutput[] = getStackJsonOutput(outputs, {
      accountKey: masterAccountKey,
      outputType: 'RdgwArtifactsOutput',
    });

    if (rdgwScriptsOutput.length === 0) {
      console.warn(`Cannot find output with RDGW reference artifacts`);
      continue;
    }

    const s3BucketName = rdgwScriptsOutput[0].bucketName;
    const S3KeyPrefix = rdgwScriptsOutput[0].keyPrefix;
    console.log('RDGW reference scripts s3 bucket name with key ', s3BucketName, S3KeyPrefix);

    const vpcOutput = VpcOutputFinder.tryFindOneByAccountAndRegionAndName({
      outputs,
      vpcName: madConfig['vpc-name'],
    });
    if (!vpcOutput) {
      console.warn(`Cannot find output with vpc name ${madConfig['vpc-name']}`);
      continue;
    }

    const vpcId = vpcOutput.vpcId;
    const vpcName = vpcOutput.vpcName;
    const subnetIds = vpcOutput.subnets.filter(s => s.subnetName === madConfig.subnet).map(s => s.subnetId);

    const madOutputs: MadOutput[] = getStackJsonOutput(outputs, {
      accountKey,
      outputType: 'MadOutput',
    });

    const madOutput = madOutputs.find(output => output.id === madConfig['dir-id']);
    if (!madOutput || !madOutput.directoryId) {
      console.warn(`Cannot find madOutput with vpc name ${madConfig['vpc-name']}`);
      continue;
    }

    const adUsersAndGroups = new ADUsersAndGroups(stack, 'RDGWHost', {
      madDeploymentConfig: madConfig,
      latestRdgwAmiId: madAutoScalingImageIdOutput.imageId,
      vpcId,
      vpcName,
      keyPairName: keyPair.keyName,
      subnetIds,
      adminPasswordArn: madOutput.passwordArn,
      s3BucketName,
      s3KeyPrefix: S3KeyPrefix,
      stackId: stack.stackId,
      stackName: stack.stackName,
      accountNames,
      userSecrets,
      accountKey,
      serviceLinkedRoleArn: madAutoScalingRoleOutput.roleArn,
      installerVersion: context.installerVersion,
    });
    adUsersAndGroups.node.addDependency(keyPair);
  }

  /**
   * Central Logging Services step 2
   * Creating Subscription Filters for handling CloudWatch Celtral Logging to S3 in log-archive account
   * Good to have in last phase, since we add subscription filter to all log groups
   */
  await cwlCentralLoggingToS3.step2({
    accountStacks,
    config: acceleratorConfig,
    outputs,
  });

  const { acceleratorBaseline } = context;

  if (['ORGANIZATIONS', 'CONTROL_TOWER'].includes(acceleratorBaseline)) {
    const masterStack = accountStacks.getOrCreateAccountStack(masterAccountKey, 'us-east-1');
    if (!masterStack) {
      console.error(`Not able to create stack for "${masterAccountKey}"`);
    } else {
      // Find the SCP artifact output
      const artifactOutput = ArtifactOutputFinder.findOneByName({
        outputs,
        artifactName: 'SCP',
      });
      const scpBucketName = artifactOutput.bucketName;
      const scpBucketPrefix = artifactOutput.keyPrefix;
      const ignoredOus = acceleratorConfig['global-options']['ignored-ous'] || [];
      const organizationAdminRole = acceleratorConfig['global-options']['organization-admin-role']!;

      await ouValidation.step1({
        scope: masterStack,
        context,
        scpBucketName,
        scpBucketPrefix,
        ignoredOus,
        organizationAdminRole,
      });
    }
  }

  /**
   *  CloudWatch Deployment step-2
   *  Creates CloudWatch Alarms
   */
  await cloudWatchDeployment.step2({
    accountStacks,
    config: acceleratorConfig,
    accounts,
  });

  /**
   * Increasing SSM Parameter Store throughput in all accounts and supported regions
   */
  await ssmDeployment.step2({
    accountStacks,
    accounts,
    config: acceleratorConfig,
    outputs,
  });

  await defaults.step3({
    accountBuckets,
    accountStacks,
    accounts,
    config: acceleratorConfig,
    centralBucket,
    outputs,
  });

  /**
   * Create Routes for GatewayLoadBalancer endpoints
   */
  await alb.step4({
    accountStacks,
    config: acceleratorConfig,
    outputs,
  });
}