CloudFront分发ID不会跨堆栈导出

时间:2019-06-03 01:37:58

标签: aws-cdk

我要在一个结构下定义两个堆栈;一个堆栈定义一个CloudFront分配和一个S3存储桶,另一个定义CodePipeline设置。

我正在从管道堆栈中引用存储桶和CloudFront分发,并且在正确导出/导入引用的存储桶属性时,CloudFront分发ID在CodePipeline堆栈中使用Ref而不是导出/导入。 看起来CodePipeline堆栈认为CloudFront发行版在其自己的范围内。

目前,我不确定这是错误还是缺少某些内容,

此堆栈定义了Bucket和CloudFront分布。

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
  }
}

这定义了同时使用存储桶和CloudFront分发的CodePipeline。

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分布时。

 "UserParameters": {
                    "Fn::Join": [
                      "",
                      [
                        "{\"distributionId\":\"",
                        {
                          "Ref": "CloudFrontCFDistribution57EFBAC6"
                        },
                        "\"}"
                      ]
                    ]
                  }

我希望CloudFront发行版能被导出,并且消费堆栈将使用Import函数来解析引用,就像发生Bucket时一样。

0 个答案:

没有答案