我正在开发一个带有几个环境的SPA:dev、preprod、prod
每个env都有一个相应的CloudFront分发版和bucket网站。
我们还有一个静态网站,里面有行为/文档/*上提供的用户手册
这个静态网站存储在一个单独的桶上
所有环境共享相同的文档,因此所有env只有一个bucket。
该项目是一个公司门户网站,因此不应公开访问用户文档。
为了实现这一点,我们正在使用OAI,因此bucket只能通过CloudFront(alambda@edge确保用户有一个有效的令牌,否则会重定向他,所以文档是私有的(。
当我使用在dev上部署时,一切都很好
terraform workspace select dev
terraform apply -var-file=dev.tfvars
但当我尝试在预印本上部署时
terraform workspace select preprod
terraform apply -var-file=preprod.tfvars
Terraform通过这种方式更改OAI ID
# module.s3.aws_s3_bucket_policy.documentation_policy will be updated in-place
~ resource "aws_s3_bucket_policy" "documentation_policy" {
bucket = "my-bucket"
~ policy = jsonencode(
~ {
~ Statement = [
~ {
Action = "s3:GetObject"
Effect = "Allow"
~ Principal = {
~ AWS = "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3U64NEVQ9IQHH" -> "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3ORU58OAALJAP"
}
Resource = "arn:aws:s3:::my-bucket/*"
Sid = ""
},
]
Version = "2012-10-17"
}
)
}
而我希望校长这样添加:
# module.s3.aws_s3_bucket_policy.documentation_policy will be updated in-place
~ resource "aws_s3_bucket_policy" "documentation_policy" {
bucket = "my-bucket"
~ policy = jsonencode(
~ {
Statement = [
{
Action = "s3:GetObject"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3U64NEVQ9IQHH"
}
Resource = "arn:aws:s3:::my-bucket/*"
Sid = ""
},
+ {
+ Action = "s3:GetObject"
+ Effect = "Allow"
+ Principal = {
+ AWS = "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3ORU58OAALJAP"
+ }
+ Resource = "arn:aws:s3:::my-bucket/*"
+ Sid = ""
+ },
]
Version = "2012-10-17"
}
)
}
有没有任何方法可以使用地形0.13.5 实现这一点
关于信息,这里是我的documentation-bucket.tf
,我在创建后在每个工作空间中导入它
resource "aws_s3_bucket" "documentation" {
bucket = var.documentation_bucket
tags = {
BillingProject = var.billing_project
Environment = var.env
Terraform = "Yes"
}
logging {
target_bucket = var.website_logs_bucket
target_prefix = "s3-access-logs/${var.documentation_bucket}/"
}
lifecycle {
prevent_destroy = true
}
}
data "aws_iam_policy_document" "documentation" {
statement {
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.documentation.arn}/*"]
principals {
type = "AWS"
identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn]
}
}
}
resource "aws_s3_bucket_policy" "documentation_policy" {
bucket = aws_s3_bucket.documentation.id
policy = data.aws_iam_policy_document.documentation.json
}
向致以最良好的问候
假设:
根据你所说的,你似乎在不同的状态文件中管理相同的资源(假设基于"[…],一旦创建,我在每个工作空间中导入"(
你这样做基本上造成了大脑分裂的局面
假设二:您正在同一个AWS帐户中部署一个S3存储桶和多个访问该存储桶的CloudFront分发版。
答案:
虽然这样做是完全可以的,但这不是它应该如何设置的。一个资源只能由一个地形状态(工作区(管理,否则您将看到这种预期但不需要的不稳定状态行为。
我建议在单个工作区配置中管理S3存储桶,甚至创建一个名为"共享"的新工作区。
在此工作区中,您可以使用terraform_remote_state数据源导入其他工作区的状态,并构建一个策略,包括从其他状态提取的所有OAI。当然,您可以在不创建新的共享工作区的情况下执行此操作。
我希望这会有所帮助,但这可能不是预期的解决方案——也许我的假设是错误的。
遗言:
在环境之间共享资源被认为不是一种好的做法,因为当您停用环境时,数据很可能会保留下来,并且管理访问可能会变得复杂和不安全。
最好像12因素应用程序的Dev/Prod Parity一样,尽可能接近环境的版本,但尽量不要共享资源。如果您觉得需要共享资源,请花点时间,再次挑战您的体系结构。