如何在AWS IAM策略中引用StringOutput?

huangapple go评论121阅读模式
英文:

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

huangapple
  • 本文由 发表于 2021年3月7日 02:29:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/66509246.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定