英文:
How do I reference a StringOutput in an AWS IAM policy
问题
我已经仔细寻找了如何做到这一点。我认为我没有正确的术语。在使用Golang的Pulumi时,如何在字符串中引用某个资源的ID呢?
例如,我创建了一个存储桶,然后我想在IAM策略中引用该存储桶的ID。这似乎是不可能的。
bucket, err := s3.NewBucket(
ctx,
photosBucketName,
&s3.BucketArgs{})
tmpJSON, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
{
"Effect": "Allow",
"Principal": "*",
"Action": []string{"s3:GetObject"},
"Resource": []string{fmt.Sprintf("arn:aws:s3:::%s/*", bucket.ID())},
},
},
})
输出结果为:
Sprintf格式%s的参数bucket.ID()的类型错误,应为github.com/pulumi/pulumi/sdk/v2/go/pulumi.IDOutput
使用photosBucketName
会导致文档格式不正确,因为存储桶名称上会生成后缀。
感谢您的时间和帮助。
英文:
I've looked high and low for how to do this. I don't think I have the right terminology. Using Pulumi with Golang how can I reference the ID of some resource in a string.
For example, I create a bucket then I want to reference that bucket's ID in an IAM policy. This seems impossible.
bucket, err := s3.NewBucket(
ctx,
photosBucketName,
&s3.BucketArgs{})
tmpJSON, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
{
"Effect": "Allow",
"Principal": "*",
"Action": []string{"s3:GetObject"},
"Resource": []string{fmt.Sprintf("arn:aws:s3:::%s/*", bucket.ID())},
},
},
})
Output being:
Sprintf format %s has arg bucket.ID() of wrong type github.com/pulumi/pulumi/sdk/v2/go/pulumi.IDOutput
Using photosBucketName
results in a malformed document because of the generated suffix on the bucket name.
Appreciate the time and help.
答案1
得分: 4
Pulumi资源返回输出(Outputs),这些值在Pulumi创建资源之前是未知的,直到上游云提供商API(在本例中为AWS S3 API)创建资源。
这意味着,如果你想将原始输出值作为标准的Go字符串进行访问,你需要告诉Pulumi引擎等待资源创建完成。你可以使用Pulumi的apply来实现这一点。
所以在你的特定示例中,我们想为我们的IAM策略构建一个JSON字符串(IAM策略只接受字符串,不能接受其他Pulumi输出)。
bucket, err := s3.NewBucket(
ctx,
photosBucketName,
&s3.BucketArgs{})
// 注意我们如何使用apply函数来包装JSON字符串的构建
bucketPolicy := bucket.Arn.ApplyT(func (arn string) (string, error) {
policyJSON, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
{
"Effect": "Allow",
"Principal": "*",
"Action": []string{"s3:GetObject"},
"Resource": []string{
arn, // 现在我可以直接传递arn
},
},
},
})
if err != nil {
return "", err
}
return string(policyJSON), nil
})
英文:
Pulumi resources return Outputs, which are values that are not known by Pulumi until the upstream cloud provider API (in this case, the AWS S3 API) until the resource is created.
What that means is that if you want to access the raw output value as a standard Go string, you'll need to somehow tell the Pulumi engine to wait until that resource has been created. You do this using Pulumi's apply
So in your particular example, we want to build a JSON string for our IAM policy (IAM policies only take strings, they can't take other Pulumi outputs).
bucket, err := s3.NewBucket(
ctx,
photosBucketName,
&s3.BucketArgs{})
// notice how we're using the apply function to wrap the building of the JSON string
bucketPolicy := bucket.Arn.ApplyT(func (arn string) (string, error) {
policyJSON, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
{
"Effect": "Allow",
"Principal": "*",
"Action": []string{"s3:GetObject"},
"Resource": []string{
arn, // I can now pass the arn directy
},
},
},
})
if err != nil {
return "", err
}
return string(policyJSON), nil
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论