constructor()

in packages/aws-rfdk/lib/core/lib/imported-acm-certificate.ts [136:237]


  constructor(scope: Construct, id: string, props: ImportedAcmCertificateProps) {
    super(scope, id);
    this.stack = Stack.of(this);
    this.env = {
      account: this.stack.account,
      region: this.stack.region,
    };

    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,
    });

    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);

    const lambda = new SingletonFunction(this, 'AcmImporter', {
      uuid: ImportedAcmCertificate.IMPORTER_UUID,
      code: Code.fromAsset(join(__dirname, '..', '..', 'lambdas', 'nodejs')),
      handler: 'x509-certificate.importCert',
      environment: {
        DATABASE: this.database.tableName,
        DEBUG: 'false',
      },
      layers: [ openSslLayer ],
      retryAttempts: 0,
      runtime: Runtime.NODEJS_18_X,
      timeout: Duration.minutes(5),
    });

    this.database.grantReadWriteData(lambda);
    this.database.grant(lambda, 'dynamodb:DescribeTable');
    props.cert.grantRead(lambda);
    props.key.grantRead(lambda);
    props.passphrase.grantRead(lambda);
    props.certChain?.grantRead(lambda);
    props.encryptionKey?.grantDecrypt(lambda);

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

    lambda.addToRolePolicy(new PolicyStatement({
      actions: [
        'acm:AddTagsToCertificate',
        'acm:ImportCertificate',
      ],
      resources: ['*'],
      conditions: {
        StringEquals: tagCondition,
      },
    }));

    // GetCertificate and DeleteCertificate don't currently support and conditions, so we have to give a broader policy
    // on them for now.
    // See https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awscertificatemanager.html#awscertificatemanager-aws_TagKeys
    // for the condition keys currently available on ACM actions.
    lambda.addToRolePolicy(new PolicyStatement({
      actions: [
        'acm:DeleteCertificate',
        'acm:DescribeCertificate',
        'acm:GetCertificate',
      ],
      resources: ['*'],
    }));

    const properties: IAcmImportCertProps = {
      X509CertificatePem: {
        Cert: props.cert.secretArn,
        Key: props.key.secretArn,
        Passphrase: props.passphrase.secretArn,
        CertChain: props.certChain ? props.certChain.secretArn : '',
      },
      Tags: [
        {
          Key: this.uniqueTag.key,
          Value: this.uniqueTag.value,
        },
        { Key: 'Name',
          Value: this.uniqueTag.value,
        },
      ],
    };

    this.resource = new CustomResource(this, 'Default', {
      serviceToken: lambda.functionArn,
      properties,
      resourceType: 'Custom::RFDK_AcmImportedCertificate',
    });

    this.certificateArn = Token.asString(this.resource.getAtt('CertificateArn'));
  }