constructor()

in lib/open-pgp-key-pair.ts [111:190]


  constructor(parent: Construct, name: string, props: OpenPGPKeyPairProps) {
    super(parent, name);

    const codeLocation = path.resolve(__dirname, 'custom-resource-handlers', 'bin', 'pgp-secret');

    const fn = new lambda.SingletonFunction(this, 'Lambda', {
      uuid: 'f25803d3-054b-44fc-985f-4860d7d6ee74',
      description: 'Generates an OpenPGP Key and stores the private key in Secrets Manager and the public key in an SSM Parameter',
      code: new lambda.AssetCode(codeLocation),
      handler: 'index.handler',
      timeout: Duration.seconds(300),
      runtime: lambda.Runtime.NODEJS_12_X,
      // add the layer that contains the GPG binary (+ shared libraries)
      layers: [new lambda.LayerVersion(this, 'GpgLayer', {
        code: lambda.Code.fromAsset(path.join(__dirname, 'custom-resource-handlers', 'layers', 'gpg-layer.zip')),
      })],
    });

    fn.addToRolePolicy(new iam.PolicyStatement({
      actions: [
        'secretsmanager:CreateSecret',
        'secretsmanager:GetSecretValue',
        'secretsmanager:UpdateSecret',
        'secretsmanager:DeleteSecret',
      ],
      resources: [Stack.of(this).formatArn({
        service: 'secretsmanager',
        resource: 'secret',
        sep: ':',
        resourceName: `${props.secretName}-??????`,
      })],
    }));

    // To allow easy migration from verison that handled the SSM parameter in the custom resource
    fn.addToRolePolicy(new iam.PolicyStatement({
      actions: ['ssm:DeleteParameter'],
      resources: ['*'],
    }));

    if (props.encryptionKey) {
      props.encryptionKey.addToResourcePolicy(new iam.PolicyStatement({
        actions: ['kms:Decrypt', 'kms:GenerateDataKey'],
        resources: ['*'],
        principals: [fn.role!.grantPrincipal],
        conditions: {
          StringEquals: {
            'kms:ViaService': `secretsmanager.${Stack.of(this).region}.amazonaws.com`,
          },
        },
      }));
    }

    const secret = new cfn.CustomResource(this, 'Resource', {
      provider: cfn.CustomResourceProvider.lambda(fn),
      properties: {
        resourceVersion: hashFileOrDirectory(codeLocation),
        identity: props.identity,
        email: props.email,
        expiry: props.expiry,
        keySizeBits: props.keySizeBits,
        secretName: props.secretName,
        keyArn: props.encryptionKey && props.encryptionKey.keyArn,
        version: props.version,
        description: props.description,
        deleteImmediately: props.removalPolicy === OpenPGPKeyPairRemovalPolicy.DESTROY_IMMEDIATELY,
      },
      removalPolicy: openPgpKeyPairRemovalPolicyToCoreRemovalPolicy(props.removalPolicy),
    });
    secret.node.addDependency(fn);

    this.credential = secretsManager.Secret.fromSecretAttributes(this, 'Credential', {
      encryptionKey: props.encryptionKey,
      secretArn: secret.getAtt('SecretArn').toString(),
    });
    this.principal = new ssm.StringParameter(this, 'Principal', {
      description: `The public part of the OpenPGP key in ${this.credential.secretArn}`,
      parameterName: props.pubKeyParameterName,
      stringValue: secret.getAtt('PublicKey').toString(),
    });
  }