Я определяю два стека под конструкцией;один стек определяет CloudFront Distribution и S3 bucket, другой - настройку CodePipeline.
Я ссылаюсь на Bucket и CloudFront Distribution из стека Pipeline, и в то время как указанные свойства Bucket правильно экспортируются / импортируются в CloudFront DistributionID использует Ref в стеке CodePipeline вместо экспорта / импорта.Похоже, что стек CodePipeline считает, что CloudFront Distribution находится в собственной области видимости.
На данный момент я не уверен, является ли это ошибкой или я что-то упустил,
Этот стекопределяет Bucket и CloudFront Distribution.
export class StaticSite extends cdk.Stack {
// expose Bucket for CodePipeline
public readonly bucket: Bucket;
// export for invalidation
public readonly cloudfrontDistribution: CloudFrontWebDistribution;
constructor(scope: cdk.Construct, id: string, props: StaticSiteProps) {
super(scope, id);
const certificateArn = [masked];
const originAccessIdentity = new CfnCloudFrontOriginAccessIdentity(this, 'OriginAccessIdentity', {
cloudFrontOriginAccessIdentityConfig: {
comment: 'Access Identity'
}
});
const bucket = new Bucket(this, 'SiteBucket', {
encryption: BucketEncryption.S3Managed,
removalPolicy: RemovalPolicy.Destroy
});
this.bucket = bucket;
bucket.addToResourcePolicy(new PolicyStatement()
.addActions('s3:GetObject')
.addResource(`${bucket.bucketArn}/*`)
.addAwsPrincipal(`arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${originAccessIdentity.cloudFrontOriginAccessIdentityId}`)
);
const distribution = new CloudFrontWebDistribution(this, 'CloudFront', {
aliasConfiguration: {
acmCertRef: certificateArn,
names: props.siteNames,
securityPolicy: props.securityPolicy || SecurityPolicyProtocol.TLSv1_2_2018
},
errorConfigurations: [
{
errorCode: 404,
errorCachingMinTtl: 300,
responsePagePath: '/index.html',
responseCode: 200
},
{
errorCode: 403,
errorCachingMinTtl: 300,
responsePagePath: '/index.html',
responseCode: 200
}
],
originConfigs: [
{
s3OriginSource: {
s3BucketSource: bucket
},
behaviors: [
{
isDefaultBehavior: true
}
]
}
]
});
this.cloudfrontDistribution = distribution
}
}
А этот определяет CodePipeline, который использует и Bucket, и CloudFront Distribution.
export class DeployPipeline extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: DeployPipelineProps) {
super(scope, id);
const artifactBucket = new Bucket(this, 'ArtifactBucket', {
encryption: BucketEncryption.KmsManaged,
removalPolicy: RemovalPolicy.Destroy
});
const cacheBucket = new Bucket(this, 'CacheBucket', {
encryption: BucketEncryption.KmsManaged,
removalPolicy: RemovalPolicy.Destroy
});
const buildProject = new PipelineProject(this, 'CodeBuild', {
buildSpec: props.buildSpec || 'buildspec.build.yaml',
cache: Cache.bucket(cacheBucket),
environment: {
computeType: props.computeType || ComputeType.Small,
buildImage: props.buildImage || LinuxBuildImage.STANDARD_2_0
},
environmentVariables: props.environmentVariables,
timeout: props.timeout || 60
});
const invalidator = new CloudFrontInvalidator(this, 'CacheInvalidator');
const pipeline = new Pipeline(this, 'DeployPipeline', {
artifactBucket: artifactBucket
});
pipeline.addStage({
name: 'Source',
actions: [
new GitHubSourceAction({
actionName: 'Fetch',
owner: 'GameOnSports',
repo: props.repository,
branch: props.branch,
oauthToken: gitHubPat,
output: new Artifact('Source')
})
]
})
pipeline.addStage({
name: 'Build',
actions: [
new CodeBuildAction({
actionName: 'Build',
input: new Artifact('Source'),
output: new Artifact('Site'),
project: buildProject
})
]
})
pipeline.addStage({
name: 'Deploy',
actions: [
new S3DeployAction({
actionName: 'S3',
input: new Artifact('Site'),
bucket: props.siteBucket,
runOrder: 1
}),
new LambdaInvokeAction({
actionName: 'Invalidate-CloudFront-Cache',
lambda: invalidator.function,
userParameters: {
distributionId: props.cloudfrontDistribution.distributionId
},
runOrder: 2
})
]
})
}
}
Как видно только из первого стекаэкспортирует атрибуты, связанные с Bucket:
"Outputs": {
"ExportsOutputFnGetAttSiteBucket397A1860ArnB404F589": {
"Value": {
"Fn::GetAtt": [
"SiteBucket397A1860",
"Arn"
]
},
"Export": {
"Name": "Fastbreakgameoninfratestfastbreaksite93FCD2C6:ExportsOutputFnGetAttSiteBucket397A1860ArnB404F589"
}
},
"ExportsOutputRefSiteBucket397A1860ADBF1315": {
"Value": {
"Ref": "SiteBucket397A1860"
},
"Export": {
"Name": "Fastbreakgameoninfratestfastbreaksite93FCD2C6:ExportsOutputRefSiteBucket397A1860ADBF1315"
}
}
}
В то время как второй стек использует функцию Ref для поиска CloudFront Distribution.
"UserParameters": {
"Fn::Join": [
"",
[
"{\"distributionId\":\"",
{
"Ref": "CloudFrontCFDistribution57EFBAC6"
},
"\"}"
]
]
}
Я ожидаю, что CloudFront Distribution будет экспортирован истек потребления будет использовать функцию импорта для разрешения ссылки, как это происходит в случае с Bucket.