Я знаю, что могу создать точку доступа и прикрепить такую политику:
exampleAccessPoint, err := pulumiS3.NewAccessPoint(ctx, accessPointName, &pulumiS3.AccessPointArgs{
AccountId: pulumi.String(exampleAcc),
Bucket: pulumi.String(exampleBucket),
Name: pulumi.String(exampleName),
Policy: pulumi.String(policy)
})
но что мне делать, если моя политика выглядит так:
policyDoc := policyDocument{
Version: "2012-10-17",
Statement: []statementEntry{
{
Effect: "Allow",
Action: []string{
"s3:GetObject",
},
Resource: []string{exampleAccesspointArn},
Principal: struct{ AWS []string }{exampleValue},
},
{
Effect: "Allow",
Action: []string{"s3:ListBucket"},
Resource: []string{accessPointArn},
Principal: struct{ AWS []string }{exampleValue},
Condition: &condition{
StringLike: &stringLike{
S3Prefix: examplePrefix,
},
},
},
},
}
Это зависит от accessPointArn, поэтому я не могу прикрепить его при создании, что мне делать?
У Пулуми есть специальный тип под названием Выход, который предназначен для управления такими отношениями ресурсов. Поскольку ваша политика зависит от ресурса ARN, а ARN не будет доступен до тех пор, пока не будет создан AccessPoint
, вам нужно будет создать политику в виде строкового вывода (а не просто простой строки), «ожидая» ARN будет доступен с помощью .ApplyT()
.
Вот несколько упрощенная версия вашего примера, показывающая, как вы можете это сделать:
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
bucket, err := s3.NewBucket(ctx, "bucket", nil)
if err != nil {
return err
}
accessPoint, err := s3.NewAccessPoint(ctx, "access-point", &s3.AccessPointArgs{
Bucket: bucket.ID(),
})
if err != nil {
return err
}
policy, err := s3.NewBucketPolicy(ctx, "policy", &s3.BucketPolicyArgs{
Bucket: bucket.ID(),
// 👇 Use .ApplyT() to wait for the ARN to be available, then compose a new string output with it.
Policy: accessPoint.Arn.ApplyT(func(arn string) (pulumi.StringOutput, error) {
p, err := json.Marshal(map[string]interface{}{
"Version": "2012-10-17",
"Statement": []map[string]interface{}{
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Principal": map[string]string{
"AWS": "exampleValue",
},
// 👇 Use the unwrapped string.
"Resource": arn + "/*",
},
},
})
if err != nil {
return pulumi.StringOutput{}, err
}
// 👇 Return a new, transformed string output.
return pulumi.String(p).ToStringOutput(), nil
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
ctx.Export("policy", policy.ID())
return nil
})
}
Это говорит Пулуми сначала создать AccessPoint
, затем BucketPolicy
. Если политика требует нескольких значений из нескольких ресурсов, вместо этого вы можете использовать .All().
Однако это общая схема: используйте .ApplyT()
, чтобы получить и преобразовать простое значение в новый результат, а затем передать преобразованный результат в качестве входных данных в другой ресурс. В документации это рассматривается более подробно:
Надеюсь, это поможет!