如何解决通过 for 循环创建多个 S3 存储桶的 CloudFormation FindInMap 模板错误
我正在尝试通过执行此 shell 脚本在一个 for 循环中创建多达 50 个具有不同(但相似)存储桶策略的 S3 存储桶:
#!/bin/bash
set -e
aws cloudformation validate-template --template-body file://$1
for i in $BUCKETS
do
aws cloudformation deploy --stack-name $i --template-file $1 --parameter-overrides \
BucketName=$i \
DefaultPrincipal=$DEFAULT_PRINCIPAL \
--capabilities CAPABILITY_NAMED_IAM --no-fail-on-empty-changeset || exit 1
done
环境变量 BUCKETS 的值为:“bucket1 bucket2 bucket3 bucket4 bucket5 bucket6”。
对于每个存储桶,不同的用户应该具有访问权限。大多数存储桶只有 DefaultPrincipal,bucket1 有另外 4 个用户,bucket2 有另外 1 个用户(如下面的 UserMap 所示)。
AWstemplateFormatVersion: 2010-09-09
Description: Create S3 bucket
Parameters:
BucketName:
Type: String
Description: Bucket name
DefaultPrincipal:
Description: Default principal ARN
Type: String
Mappings:
UserMap:
bucket1:
users:
- 'user1-abc'
- 'user2-xyz'
- 'user3-qwe'
- 'user4-asd'
bucket3:
users:
- 'user5-yxc'
Conditions:
FirstUserCondition: !Or
- !Equals
- !Ref BucketName
- bucket1
- !Equals
- !Ref BucketName
- bucket3
SecondUserCondition: !Equals
- !Ref BucketName
- bucket1
ThirdUserCondition: !Equals
- !Ref BucketName
- bucket1
FourthUserCondition: !Equals
- !Ref BucketName
- bucket1
Resources:
S3BucketTest:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Ref BucketName
S3BucketPolicyTest:
Type: 'AWS::S3::BucketPolicy'
DependsOn: S3BucketTest
Properties:
Bucket: !Ref BucketName
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: TestPolicy
Action:
- 's3:PutObject'
- 's3:Getobject'
- 's3:AbortMultipartUpload'
- 's3:List*'
Effect: Allow
Resource:
- !Join
- ':'
- - 'arn:aws:s3::'
- !Ref BucketName
- !Join
- /
- - !Join
- ':'
- - 'arn:aws:s3::'
- !Ref BucketName
- '*'
Principal:
AWS:
- !ImportValue
DefaultPrincipal
- !If
- FirstUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 0
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::Novalue'
- !If
- SecondUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 1
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::Novalue'
- !If
- ThirdUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 2
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::Novalue'
- !If
- FourthUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 3
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::Novalue'
然而,这总是导致以下错误:
An error occurred (ValidationError) when calling the CreateChangeSet operation: Template error: Unable to get mapping for UserMap::bucket2::users
An error occurred (ValidationError) when calling the CreateChangeSet operation: Template error: Fn::Select cannot select nonexistent value at index 1
解决方法
由于这个错误,我不得不通过在 UserMap 中列出所有存储桶和用户字符串来做一个非常丑陋的解决方法:
AWSTemplateFormatVersion: 2010-09-09
Description: Create S3 bucket
Parameters:
BucketName:
Type: String
Description: Bucket name
DefaultPrincipal:
Description: Default principal ARN
Type: String
Mappings:
UserMap:
bucket1:
users:
- 'user1-abc'
- 'user2-xyz'
- 'user3-qwe'
- 'user4-asd'
bucket2:
users:
- ''
- ''
- ''
- ''
bucket3:
users:
- 'user5-yxc'
- ''
- ''
- ''
bucket4:
users:
- ''
- ''
- ''
- ''
bucket5:
users:
- ''
- ''
- ''
- ''
bucket6:
users:
- ''
- ''
- ''
- ''
Conditions:
FirstUserCondition: !Not
- !Equals
- ''
- !Select
- 0
- !FindInMap
- UserMap
- !Ref BucketName
- users
SecondUserCondition: !Not
- !Equals
- ''
- !Select
- 1
- !FindInMap
- UserMap
- !Ref BucketName
- users
ThirdUserCondition: !Not
- !Equals
- ''
- !Select
- 2
- !FindInMap
- UserMap
- !Ref BucketName
- users
FourthUserCondition: !Not
- !Equals
- ''
- !Select
- 3
- !FindInMap
- UserMap
- !Ref BucketName
- users
Resources:
S3BucketTest:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Ref BucketName
S3BucketPolicyTest:
Type: 'AWS::S3::BucketPolicy'
DependsOn: S3BucketTest
Properties:
Bucket: !Ref BucketName
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: TestPolicy
Action:
- 's3:PutObject'
- 's3:GetObject'
- 's3:AbortMultipartUpload'
- 's3:List*'
Effect: Allow
Resource:
- !Join
- ':'
- - 'arn:aws:s3::'
- !Ref BucketName
- !Join
- /
- - !Join
- ':'
- - 'arn:aws:s3::'
- !Ref BucketName
- '*'
Principal:
AWS:
- !ImportValue
DefaultPrincipal
- !If
- FirstUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 0
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::NoValue'
- !If
- SecondUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 1
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::NoValue'
- !If
- ThirdUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 2
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::NoValue'
- !If
- FourthUserCondition
- !Sub
- >-
arn:aws:iam::${AccountId}:user/${UserName}
- AccountId: !Ref AWS::AccountId
UserName: !Select
- 3
- !FindInMap
- UserMap
- !Ref BucketName
- users
- !Ref 'AWS::NoValue'
有没有更好的方法来做到这一点?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。