constructor()

in packages/aws-rfdk/lib/core/lib/x509-certificate.ts [161:233]


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

    this.database = new Table(this, 'Table', {
      partitionKey: { name: 'PhysicalId', type: AttributeType.STRING },
      sortKey: { name: 'CustomResource', type: AttributeType.STRING },
      removalPolicy: RemovalPolicy.DESTROY,
      encryption: TableEncryption.AWS_MANAGED,
      billingMode: BillingMode.PAY_PER_REQUEST,
      pointInTimeRecovery: true,
    });

    this.passphrase = new Secret(this, 'Passphrase', {
      description: `Passphrase for the private key of the X509Certificate ${Names.uniqueId(this)}`,
      encryptionKey: props.encryptionKey,
      generateSecretString: {
        excludeCharacters: '"()$\'', // Exclude characters that might interact with command shells.
        excludePunctuation: true,
        includeSpace: false,
        passwordLength: 24,
        requireEachIncludedType: true,
      },
    });

    const region = Stack.of(this).region;
    const openSslLayerName = 'openssl-al2';
    const openSslLayerArns: any = ARNS[openSslLayerName];
    const openSslLayerArn = openSslLayerArns[region];
    const openSslLayer = LayerVersion.fromLayerVersionArn(this, 'OpenSslLayer', openSslLayerArn);

    /*
     * We cannot make this a singleton function; doing so would create circular references in the lambda role (to sign
     * a cert we need a cert that this lambda generated).
     */
    this.lambdaFunc = new LambdaFunction(this, 'Generator', {
      description: `Used by a X509Certificate ${Names.uniqueId(this)} to generate certificates.`,
      code: props.lambdaCode,
      environment: {
        DATABASE: this.database.tableName,
        DEBUG: 'false',
      },
      runtime: Runtime.NODEJS_18_X,
      layers: [ openSslLayer ],
      handler: props.lambdaHandler,
      timeout: Duration.seconds(90),
      logRetention: RetentionDays.ONE_WEEK,
    });
    this.database.grantReadWriteData(this.lambdaFunc);
    this.database.grant(this.lambdaFunc, 'dynamodb:DescribeTable');
    props.encryptionKey?.grantEncrypt(this.lambdaFunc);
    this.passphrase.grantRead(this.lambdaFunc);

    const uniqueValue = crypto.createHash('md5').update(Names.uniqueId(this)).digest('hex');
    this.uniqueTag = new Tag(
      `X509SecretGrant-${uniqueValue.slice(0, 8).toUpperCase()}`,
      uniqueValue,
    );
    const tagCondition: { [key: string]: any } = {};
    tagCondition[`secretsmanager:ResourceTag/${this.uniqueTag.key}`] = this.uniqueTag.value;

    this.lambdaFunc.addToRolePolicy(new PolicyStatement({
      actions: [
        'secretsmanager:CreateSecret',
        'secretsmanager:DeleteSecret',
        'secretsmanager:TagResource',
        'secretsmanager:PutSecretValue',
      ],
      resources: ['*'],
      conditions: {
        StringEquals: tagCondition,
      },
    }));
  }