constructor()

in lib/change-controller.ts [63:133]


  constructor(scope: Construct, id: string, props: ChangeControllerProps) {
    super(scope, id);

    let changeControlBucket = props.changeControlBucket;
    let ownBucket: s3.Bucket | undefined;

    if (!changeControlBucket) {
      changeControlBucket = ownBucket = new s3.Bucket(this, 'Calendar', {
        removalPolicy: RemovalPolicy.DESTROY,
        versioned: true,
      });
    }

    // const changeControlBucket = props.changeControlBucket || new s3.Bucket(this, 'Bucket', { versioned: true });
    const changeControlObjectKey = props.changeControlObjectKey || 'change-control.ics';

    const fn = new nodejs.NodejsFunction(this, 'Function', {
      description: `Enforces a Change Control Policy into CodePipeline's ${props.pipelineStage.stageName} stage`,
      entry: path.join(__dirname, 'change-control-lambda', 'index.ts'),
      runtime: lambda.Runtime.NODEJS_12_X,
      environment: {
        // CAPITAL punishment 👌🏻
        CHANGE_CONTROL_BUCKET_NAME: changeControlBucket.bucketName,
        CHANGE_CONTROL_OBJECT_KEY: changeControlObjectKey,
        PIPELINE_NAME: props.pipelineStage.pipeline.pipelineName,
        STAGE_NAME: props.pipelineStage.stageName,
      },
      timeout: Duration.seconds(300),
    });

    fn.addToRolePolicy(new iam.PolicyStatement({
      resources: [`${props.pipelineStage.pipeline.pipelineArn}/${props.pipelineStage.stageName}`],
      actions: ['codepipeline:EnableStageTransition', 'codepipeline:DisableStageTransition'],
    }));

    changeControlBucket.grantRead(fn, props.changeControlObjectKey);

    if (ownBucket) {
      ownBucket.addObjectCreatedNotification(new s3_notifications.LambdaDestination(fn), {
        prefix: changeControlObjectKey,
      });
    }

    this.failureAlarm = new cloudwatch.Alarm(this, 'Failed', {
      metric: fn.metricErrors(),
      threshold: 1,
      datapointsToAlarm: 1,
      period: Duration.seconds(300),
      evaluationPeriods: 1,
    });

    const schedule = props.schedule || events.Schedule.expression('rate(15 minutes)');

    // Run this on a schedule
    new events.Rule(this, 'Rule', {
      // tslint:disable-next-line:max-line-length
      description: `Run the change controller for promotions into ${props.pipelineStage.pipeline.pipelineName}'s ${props.pipelineStage.stageName} on a ${schedule} schedule`,
      schedule,
      targets: [new events_targets.LambdaFunction(fn)],
    });

    if (props.createOutputs !== false) {
      new CfnOutput(this, 'ChangeControlBucketKey', {
        value: changeControlObjectKey,
      });

      new CfnOutput(this, 'ChangeControlBucket', {
        value: changeControlBucket.bucketName,
      });
    }
  }