constructor()

in packages/aws-cdk-lib/aws-s3/lib/bucket.ts [2193:2314]


  constructor(scope: Construct, id: string, props: BucketProps = {}) {
    super(scope, id, {
      physicalName: props.bucketName,
    });
    // Enhanced CDK Analytics Telemetry
    addConstructMetadata(this, props);

    this.notificationsHandlerRole = props.notificationsHandlerRole;
    this.notificationsSkipDestinationValidation = props.notificationsSkipDestinationValidation;

    const { bucketEncryption, encryptionKey } = this.parseEncryption(props);
    this.encryptionKey = encryptionKey;

    Bucket.validateBucketName(this.physicalName);

    const websiteConfiguration = this.renderWebsiteConfiguration(props);
    this.isWebsite = (websiteConfiguration !== undefined);

    const objectLockConfiguration = this.parseObjectLockConfig(props);
    const replicationConfiguration = this.renderReplicationConfiguration(props);
    this.replicationRoleArn = replicationConfiguration?.role;
    this.objectOwnership = props.objectOwnership;
    this.transitionDefaultMinimumObjectSize = props.transitionDefaultMinimumObjectSize;
    const resource = new CfnBucket(this, 'Resource', {
      bucketName: this.physicalName,
      bucketEncryption,
      versioningConfiguration: props.versioned ? { status: 'Enabled' } : undefined,
      lifecycleConfiguration: Lazy.any({ produce: () => this.parseLifecycleConfiguration() }),
      websiteConfiguration,
      publicAccessBlockConfiguration: props.blockPublicAccess,
      metricsConfigurations: Lazy.any({ produce: () => this.parseMetricConfiguration() }),
      corsConfiguration: Lazy.any({ produce: () => this.parseCorsConfiguration() }),
      accessControl: Lazy.string({ produce: () => this.accessControl }),
      loggingConfiguration: this.parseServerAccessLogs(props),
      inventoryConfigurations: Lazy.any({ produce: () => this.parseInventoryConfiguration() }),
      ownershipControls: Lazy.any({ produce: () => this.parseOwnershipControls() }),
      accelerateConfiguration: props.transferAcceleration ? { accelerationStatus: 'Enabled' } : undefined,
      intelligentTieringConfigurations: this.parseTieringConfig(props),
      objectLockEnabled: objectLockConfiguration ? true : props.objectLockEnabled,
      objectLockConfiguration: objectLockConfiguration,
      replicationConfiguration,
    });
    this._resource = resource;

    resource.applyRemovalPolicy(props.removalPolicy);

    this.eventBridgeEnabled = props.eventBridgeEnabled;

    this.bucketName = this.getResourceNameAttribute(resource.ref);
    this.bucketArn = this.getResourceArnAttribute(resource.attrArn, {
      region: '',
      account: '',
      service: 's3',
      resource: this.physicalName,
    });

    this.bucketDomainName = resource.attrDomainName;
    this.bucketWebsiteUrl = resource.attrWebsiteUrl;
    this.bucketWebsiteDomainName = Fn.select(2, Fn.split('/', this.bucketWebsiteUrl));
    this.bucketDualStackDomainName = resource.attrDualStackDomainName;
    this.bucketRegionalDomainName = resource.attrRegionalDomainName;

    this.disallowPublicAccess = props.blockPublicAccess && props.blockPublicAccess.blockPublicPolicy;
    this.accessControl = props.accessControl;

    // Enforce AWS Foundational Security Best Practice
    if (props.enforceSSL) {
      this.enforceSSLStatement();
      this.minimumTLSVersionStatement(props.minimumTLSVersion);
    } else if (props.minimumTLSVersion) {
      throw new ValidationError('\'enforceSSL\' must be enabled for \'minimumTLSVersion\' to be applied', this);
    }

    if (props.serverAccessLogsBucket instanceof Bucket) {
      props.serverAccessLogsBucket.allowLogDelivery(this, props.serverAccessLogsPrefix);
    // It is possible that `serverAccessLogsBucket` was specified but is some other `IBucket`
    // that cannot have the ACLs or bucket policy applied. In that scenario, we should only
    // setup log delivery permissions to `this` if a bucket was not specified at all, as documented.
    // For example, we should not allow log delivery to `this` if given an imported bucket or
    // another situation that causes `instanceof` to fail
    } else if (!props.serverAccessLogsBucket && props.serverAccessLogsPrefix) {
      this.allowLogDelivery(this, props.serverAccessLogsPrefix);
    } else if (props.serverAccessLogsBucket) {
      // A `serverAccessLogsBucket` was provided but it is not a concrete `Bucket` and it
      // may not be possible to configure the ACLs or bucket policy as required.
      Annotations.of(this).addWarningV2('@aws-cdk/aws-s3:accessLogsPolicyNotAdded',
        `Unable to add necessary logging permissions to imported target bucket: ${props.serverAccessLogsBucket}`,
      );
    }

    for (const inventory of props.inventories ?? []) {
      this.addInventory(inventory);
    }

    // Add all bucket metric configurations rules
    (props.metrics || []).forEach(this.addMetric.bind(this));
    // Add all cors configuration rules
    (props.cors || []).forEach(this.addCorsRule.bind(this));

    // Add all lifecycle rules
    (props.lifecycleRules || []).forEach(this.addLifecycleRule.bind(this));

    if (props.publicReadAccess) {
      if (props.blockPublicAccess === undefined) {
        throw new ValidationError('Cannot use \'publicReadAccess\' property on a bucket without allowing bucket-level public access through \'blockPublicAccess\' property.', this);
      }

      this.grantPublicAccess();
    }

    if (props.autoDeleteObjects) {
      if (props.removalPolicy !== RemovalPolicy.DESTROY) {
        throw new ValidationError('Cannot use \'autoDeleteObjects\' property on a bucket without setting removal policy to \'DESTROY\'.', this);
      }

      this.enableAutoDeleteObjects();
    }

    if (this.eventBridgeEnabled) {
      this.enableEventBridgeNotification();
    }
  }