in packages/aws-cdk-lib/aws-cloudfront/lib/web-distribution.ts [1081:1202]
private toOriginProperty(originConfig: SourceConfigurationRender, originId: string): CfnDistribution.OriginProperty {
if (
!originConfig.s3OriginSource &&
!originConfig.customOriginSource
) {
throw new cdk.ValidationError(
'There must be at least one origin source - either an s3OriginSource, a customOriginSource',
this,
);
}
if (originConfig.customOriginSource && originConfig.s3OriginSource) {
throw new cdk.ValidationError(
'There cannot be both an s3OriginSource and a customOriginSource in the same SourceConfiguration.',
this,
);
}
if ([
originConfig.originHeaders,
originConfig.s3OriginSource?.originHeaders,
originConfig.customOriginSource?.originHeaders,
].filter(x => x).length > 1) {
throw new cdk.ValidationError('Only one originHeaders field allowed across origin and failover origins', this);
}
if ([
originConfig.originPath,
originConfig.s3OriginSource?.originPath,
originConfig.customOriginSource?.originPath,
].filter(x => x).length > 1) {
throw new cdk.ValidationError('Only one originPath field allowed across origin and failover origins', this);
}
if ([
originConfig.originShieldRegion,
originConfig.s3OriginSource?.originShieldRegion,
originConfig.customOriginSource?.originShieldRegion,
].filter(x => x).length > 1) {
throw new cdk.ValidationError('Only one originShieldRegion field allowed across origin and failover origins', this);
}
const headers = originConfig.originHeaders ?? originConfig.s3OriginSource?.originHeaders ?? originConfig.customOriginSource?.originHeaders;
const originHeaders: CfnDistribution.OriginCustomHeaderProperty[] = [];
if (headers) {
Object.keys(headers).forEach((key) => {
const oHeader: CfnDistribution.OriginCustomHeaderProperty = {
headerName: key,
headerValue: headers[key],
};
originHeaders.push(oHeader);
});
}
let s3OriginConfig: CfnDistribution.S3OriginConfigProperty | undefined;
if (originConfig.s3OriginSource) {
// first case for backwards compatibility
if (originConfig.s3OriginSource.originAccessIdentity) {
// grant CloudFront OriginAccessIdentity read access to S3 bucket
// Used rather than `grantRead` because `grantRead` will grant overly-permissive policies.
// Only GetObject is needed to retrieve objects for the distribution.
// This also excludes KMS permissions; currently, OAI only supports SSE-S3 for buckets.
// Source: https://aws.amazon.com/blogs/networking-and-content-delivery/serving-sse-kms-encrypted-content-from-s3-using-cloudfront/
originConfig.s3OriginSource.s3BucketSource.addToResourcePolicy(new iam.PolicyStatement({
resources: [originConfig.s3OriginSource.s3BucketSource.arnForObjects('*')],
actions: ['s3:GetObject'],
principals: [originConfig.s3OriginSource.originAccessIdentity.grantPrincipal],
}));
s3OriginConfig = {
originAccessIdentity: `origin-access-identity/cloudfront/${originConfig.s3OriginSource.originAccessIdentity.originAccessIdentityId}`,
};
} else {
s3OriginConfig = {};
}
}
const connectionAttempts = originConfig.connectionAttempts ?? 3;
if (connectionAttempts < 1 || 3 < connectionAttempts || !Number.isInteger(connectionAttempts)) {
throw new cdk.ValidationError('connectionAttempts: You can specify 1, 2, or 3 as the number of attempts.', this);
}
const connectionTimeout = (originConfig.connectionTimeout || cdk.Duration.seconds(10)).toSeconds();
if (connectionTimeout < 1 || 10 < connectionTimeout || !Number.isInteger(connectionTimeout)) {
throw new cdk.ValidationError('connectionTimeout: You can specify a number of seconds between 1 and 10 (inclusive).', this);
}
const originProperty: CfnDistribution.OriginProperty = {
id: originId,
domainName: originConfig.s3OriginSource
? originConfig.s3OriginSource.s3BucketSource.bucketRegionalDomainName
: originConfig.customOriginSource!.domainName,
originPath: originConfig.originPath ?? originConfig.customOriginSource?.originPath ?? originConfig.s3OriginSource?.originPath,
originCustomHeaders:
originHeaders.length > 0 ? originHeaders : undefined,
s3OriginConfig,
originShield: this.toOriginShieldProperty(originConfig),
customOriginConfig: originConfig.customOriginSource
? {
httpPort: originConfig.customOriginSource.httpPort || 80,
httpsPort: originConfig.customOriginSource.httpsPort || 443,
originKeepaliveTimeout:
(originConfig.customOriginSource.originKeepaliveTimeout &&
originConfig.customOriginSource.originKeepaliveTimeout.toSeconds()) ||
5,
originReadTimeout:
(originConfig.customOriginSource.originReadTimeout &&
originConfig.customOriginSource.originReadTimeout.toSeconds()) ||
30,
originProtocolPolicy:
originConfig.customOriginSource.originProtocolPolicy ||
OriginProtocolPolicy.HTTPS_ONLY,
originSslProtocols: originConfig.customOriginSource
.allowedOriginSSLVersions || [OriginSslPolicy.TLS_V1_2],
}
: undefined,
connectionAttempts,
connectionTimeout,
};
return originProperty;
}