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