使用AWS CDK for S3存储桶创建了Cloud Front Web分发,而无需公共访问。能够创建Origin访问身份,并进行部署,但部署成功后,我会在浏览器上获得拒绝访问的响应。
将“从源的存储桶授予读取权限”设置设置为“否”,手动将其设置为“是”,一切都会很好,但是此设置需要通过AWS CDK和python实现。下面是我的代码。
from aws_cdk import aws_cloudfront as front, aws_s3 as s3
class CloudFrontStack(core.Stack):
def __init__(self, scope: core.Construct, idx: str, **kwargs) -> None:
super().__init__(scope, idx, **kwargs)
bucket = s3.Bucket.from_bucket_name(self, 'CloudFront',bucket_name="bucket_name")
oia = aws_cloudfront.OriginAccessIdentity(self, 'OIA', comment="Created By CDK")
bucket.grant_read(oia)
s3_origin_source = aws_cloudfront.S3OriginConfig(s3_bucket_source=bucket, origin_access_identity=oia)
source_config = aws_cloudfront.SourceConfiguration(s3_origin_source=s3_origin_source,
origin_path="bucket_path",
behaviors=[aws_cloudfront.Behavior(is_default_behavior=True)])
aws_cloudfront.CloudFrontWebDistribution(self, "cloud_front_name",
origin_configs=[source_config],
comment='Cloud Formation created',
default_root_object='index.html')
我也尝试将权限添加到,但仍然没有运气。
policyStatement = aws_iam.PolicyStatement()
policyStatement.add_resources()
policyStatement.add_actions('s3:GetBucket*');
policyStatement.add_actions('s3:GetObject*');
policyStatement.add_actions('s3:List*');
policyStatement.add_resources(bucket.bucket_arn);
policyStatement.add_canonical_user_principal(oia.cloud_front_origin_access_identity_s3_canonical_user_id);
code_bucket.add_to_resource_policy(policyStatement);
我试图模仿这一点,并且能够将Cloudfront发行成功地集成到私有S3存储桶中。但是,我将TS用于堆栈。我敢肯定,将下面的代码与Python版本关联起来会很容易。假设其中有一个index.html
文件dist
aws-cdk v1.31.0(截至2020年3月29日)
import { App, Stack, StackProps } from '@aws-cdk/core';
import { BucketDeployment, Source } from '@aws-cdk/aws-s3-deployment';
import { CloudFrontWebDistribution, OriginAccessIdentity } from '@aws-cdk/aws-cloudfront';
import { BlockPublicAccess, Bucket, BucketEncryption } from '@aws-cdk/aws-s3';
export class HelloCdkStack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
const myFirstBucket = new Bucket(this, 'MyFirstBucket', {
versioned: true,
encryption: BucketEncryption.S3_MANAGED,
bucketName: 'cdk-example-bucket-for-test',
websiteIndexDocument: 'index.html',
blockPublicAccess: BlockPublicAccess.BLOCK_ALL
});
new BucketDeployment(this, 'DeployWebsite', {
sources: [Source.asset('dist')],
destinationBucket: myFirstBucket
});
const oia = new OriginAccessIdentity(this, 'OIA', {
comment: "Created by CDK"
});
myFirstBucket.grantRead(oia);
new CloudFrontWebDistribution(this, 'cdk-example-distribution', {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: myFirstBucket,
originAccessIdentity: oia
},
behaviors: [
{ isDefaultBehavior: true }
]
}
]
});
}
}
==更新== [没有Web托管的S3存储桶]
这是一个示例,其中S3用作没有Web托管的原始服务器。它按预期工作。
import { App, Stack, StackProps } from '@aws-cdk/core';
import { BucketDeployment, Source } from '@aws-cdk/aws-s3-deployment';
import { CloudFrontWebDistribution, OriginAccessIdentity } from '@aws-cdk/aws-cloudfront';
import { BlockPublicAccess, Bucket, BucketEncryption } from '@aws-cdk/aws-s3';
export class CloudfrontS3Stack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
// Create bucket (which is not a static website host), encrypted AES-256 and block all public access
// Only Cloudfront access to S3 bucket
const testBucket = new Bucket(this, 'TestS3Bucket', {
encryption: BucketEncryption.S3_MANAGED,
bucketName: 'cdk-static-asset-dmahapatro',
blockPublicAccess: BlockPublicAccess.BLOCK_ALL
});
// Create Origin Access Identity to be use Canonical User Id in S3 bucket policy
const originAccessIdentity = new OriginAccessIdentity(this, 'OAI', {
comment: "Created_by_dmahapatro"
});
testBucket.grantRead(originAccessIdentity);
// Create Cloudfront distribution with S3 as Origin
const distribution = new CloudFrontWebDistribution(this, 'cdk-example-distribution', {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: testBucket,
originAccessIdentity: originAccessIdentity
},
behaviors: [
{ isDefaultBehavior: true }
]
}
]
});
// Upload items in bucket and provide distribution to create invalidations
new BucketDeployment(this, 'DeployWebsite', {
sources: [Source.asset('dist')],
destinationBucket: testBucket,
distribution,
distributionPaths: ['/images/*.png']
});
}
}
==更新== [导入了S3存储桶,而不是在同一堆栈中创建]
当我们引用现有的S3存储桶时,可以重新创建该问题。
原因:问题
的根本原因在于此行代码。autoCreatePolicy
将始终false
用于进口的S3存储桶。为了使addResourcePolicy
工作正常,导入的存储桶必须已经有一个现有的存储桶策略,以便可以附加新的策略语句,或者手动创建新的存储桶策略并添加策略语句。在下面的代码中,我手动创建了存储桶策略并添加了所需的策略语句。这与github问题#941非常接近,但是细微的区别是在堆栈中创建存储桶与导入已创建的存储桶之间。
import { App, Stack, StackProps } from '@aws-cdk/core';
import { CloudFrontWebDistribution, OriginAccessIdentity } from '@aws-cdk/aws-cloudfront';
import { Bucket, BucketPolicy } from '@aws-cdk/aws-s3';
import { PolicyStatement } from '@aws-cdk/aws-iam';
export class CloudfrontS3Stack extends Stack {
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
const testBucket = Bucket.fromBucketName(this, 'TestBucket', 'dmahapatro-personal-bucket');
// Create Origin Access Identity to be use Canonical User Id in S3 bucket policy
const originAccessIdentity = new OriginAccessIdentity(this, 'OAI', {
comment: "Created_by_dmahapatro"
});
// This does not seem to work if Bucket.fromBucketName is used
// It works for S3 buckets which are created as part of this stack
// testBucket.grantRead(originAccessIdentity);
// Explicitly add Bucket Policy
const policyStatement = new PolicyStatement();
policyStatement.addActions('s3:GetBucket*');
policyStatement.addActions('s3:GetObject*');
policyStatement.addActions('s3:List*');
policyStatement.addResources(testBucket.bucketArn);
policyStatement.addResources(`${testBucket.bucketArn}/*`);
policyStatement.addCanonicalUserPrincipal(originAccessIdentity.cloudFrontOriginAccessIdentityS3CanonicalUserId);
// testBucket.addToResourcePolicy(policyStatement);
// Manually create or update bucket policy
if( !testBucket.policy ) {
new BucketPolicy(this, 'Policy', { bucket: testBucket }).document.addStatements(policyStatement);
} else {
testBucket.policy.document.addStatements(policyStatement);
}
// Create Cloudfront distribution with S3 as Origin
const distribution = new CloudFrontWebDistribution(this, 'cdk-example-distribution', {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: testBucket,
originAccessIdentity: originAccessIdentity
},
behaviors: [
{ isDefaultBehavior: true }
]
}
]
});
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句