constructor()

in src/riff-raff-yaml-file/index.ts [210:303]


  constructor(app: App) {
    this.allCdkStacks = app.node.findAll().filter((_) => _ instanceof GuStack) as GuStack[];
    const allowedStages = new Set(this.allCdkStacks.map(({ stage }) => stage));
    this.allStageTags = Array.from(allowedStages);
    this.allStackTags = Array.from(new Set(this.allCdkStacks.map(({ stack }) => stack)));
    this.allRegions = Array.from(new Set(this.allCdkStacks.map(({ region }) => region)));

    this.validateStacksInApp();
    this.validateAllRegionsAreResolved();

    this.outdir = app.outdir;

    const deployments = new Map<RiffRaffDeploymentName, RiffRaffDeploymentProps>();

    const groupedStacks: GroupedCdkStacks = groupByClassNameStackRegionStage(this.allCdkStacks);

    Object.values(groupedStacks).forEach((stackTagGroup) => {
      Object.values(stackTagGroup).forEach((regionGroup) => {
        Object.values(regionGroup).forEach((stageGroup) => {
          const stacks: GuStack[] = Object.values(stageGroup).flat();

          // The items in `stacks` only differ by stage, so we can just use the first item in the list.
          const [stack] = stacks;

          if (!stack) {
            throw new Error("Unable to produce a working riff-raff.yaml file; there are no stacks!");
          }

          const lambdas = this.getLambdas(stack);
          const autoscalingGroups = this.getAutoScalingGroups(stack);

          const artifactUploads: RiffRaffDeployment[] = [
            lambdas.filter((_) => !_.withoutArtifactUpload).map(uploadLambdaArtifact),
            autoscalingGroups.map(uploadAutoscalingArtifact),
          ].flat();
          artifactUploads.forEach(({ name, props }) => deployments.set(name, props));

          const parentStacks: RiffRaffDeployment[] = this.getGuStackDependencies(stack).map((x) =>
            cloudFormationDeployment([x], [], this.outdir),
          );

          const cfnDeployment = cloudFormationDeployment(stacks, [...artifactUploads, ...parentStacks], this.outdir);
          deployments.set(cfnDeployment.name, cfnDeployment.props);

          const lambdasWithoutAnAlias = lambdas.filter((lambda) => lambda.alias === undefined);
          // If the Lambda has an alias it is using versioning. When using versioning, there is no need for Riff-Raff
          // to modify the unpublished version of the function
          lambdasWithoutAnAlias.forEach((lambda) => {
            const lambdaDeployment = updateLambdaDeployment(lambda, cfnDeployment);
            deployments.set(lambdaDeployment.name, lambdaDeployment.props);
          });

          /*
          Instances in an ASG with an `AutoScalingRollingUpdate` update policy are rotated via CloudFormation.
          Therefore, they do not need to also perform an `autoscaling` deployment via Riff-Raff.
           */
          const legacyAutoscalingGroups = autoscalingGroups.filter((asg) => {
            const { cfnOptions } = asg.node.defaultChild as CfnAutoScalingGroup;
            const { updatePolicy } = cfnOptions;
            return updatePolicy?.autoScalingRollingUpdate === undefined;
          });

          legacyAutoscalingGroups.forEach((asg) => {
            const asgDeployment = autoscalingDeployment(asg, cfnDeployment);
            deployments.set(asgDeployment.name, asgDeployment.props);
          });

          const amiParametersToTags = getAmiParameters(autoscalingGroups);

          const minInServiceParamMap = HorizontallyScalingDeploymentProperties.getInstance(stack).asgToParamMap;
          const minInServiceAsgs = autoscalingGroups.filter((asg) => minInServiceParamMap.has(asg.node.id));
          const minInstancesInServiceParameters = getMinInstancesInServiceParameters(minInServiceAsgs);

          deployments.set(cfnDeployment.name, {
            ...cfnDeployment.props,
            parameters: {
              ...cfnDeployment.props.parameters,

              // only add the `amiParametersToTags` property if there are some
              ...(autoscalingGroups.length > 0 && { amiParametersToTags }),

              // only add the `minInstancesInServiceParameters` property if there are some
              ...(minInServiceAsgs.length > 0 && { minInstancesInServiceParameters }),
            },
          });
        });
      });
    });

    this.riffRaffYaml = {
      allowedStages,
      deployments,
    };
  }