yaml - 如何根据 IAM 角色 CloudFormation 模板中的参数提供不同的条件
问题描述
我正在为我将通过 STS 代入的 IAM 角色编写 CloudFormation 模板。我需要添加一个键等于一个值的条件,其中键和值都取决于“阶段”参数。我能够根据参数以编程方式更改的值,但是我所有基于 Stage 更改密钥的尝试都失败了。
我已经尝试使用 map 和 !FindInMap 来获取正确的键,并尝试使用 !If 来构建两种情况的条件。
在第一种情况下...
Mappings:
Constants:
beta:
Id: "beta.example.com"
Endpoint: "beta-link.example.com/api/oauth2/v2:aud"
prod:
Id: "example.com"
Endpoint: "link.example.com/api/oauth2/v2:aud"
AssumeRolePolicyDocument:
Statement:
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
!FindInMap [Constants, !Ref Stage, Endpoint]:
- !FindInMap [Constants, !Ref Stage, Id]
...我收到一个错误:map keys must be strings; received a map instead
在第二种情况下...
AssumeRolePolicyDocument:
Statement:
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
!If
- !Equals [!Ref Stage, prod]
- StringEquals:
"link.example.com/api/oauth2/v2:aud": "example.com"
- StringEquals:
"beta-link.example.com/api/oauth2/v2:aud": "beta.example.com"
...我遇到了另一个错误:Template format error: Conditions can only be boolean operations on parameters and other conditions
简而言之,如何指定键和值都依赖于参数的条件?
解决方案
我连续挣扎了大约8个小时,终于找到了这个问题的答案。只是为了观众,我想总结一下这个问题:
问题陈述:作为一名基础设施工程师,我想为 AWS::IAM::Role 编写一个 cloudformation 资源,它定义了一个带有 Condition 子句的 AssumeRolePolicyDocument,其中需要对密钥进行参数化。还有一个问题是我们可以使用带有条件键的内在函数吗?
答:是的,可以使用开箱即用的样式。AssumeRolePolicyDocument是一个字符串类型,根据“AWS::IAM::Role”的 AWS Cloudformation文档。因此,无需使用 YAML 样式数据到AssumeRolePolicyDocument属性,只需使用Fn::Sub传递原始 JSON 格式的 Assumerole 策略并使用变量替换密钥,而不会出现任何问题或警告。以下是您可以使用的示例。这是我试图解决的一个复杂用例,但它展示了如何使用 !SUB、!Select 等替换 IAM Condition 子句下的键。
ExampleAppRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub ${Environment}-ExampleAppRole
AssumeRolePolicyDocument:
Fn::Sub:
- |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS::AccountId}:oidc-provider/oidc.eks.${AWS::Region}.amazonaws.com/id/${id}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${clusterid}": "${serviceaccount}"
}
}
}
]
}
-
clusterid: !Join ["",[!Sub "oidc.eks.${AWS::Region}.amazonaws.com/id/",!Select [1, !Split ["//", !Select [0, !Split [".", !GetAtt Cluster.Endpoint]]]],":sub"]]
id: !Select [1, !Split ["//", !Select [0, !Split [".", !GetAtt Cluster.Endpoint]]]]
Region: !Sub ${AWS::Region}
serviceaccount: system:serviceaccount:default:awsiamroleexample
Path: /
ManagedPolicyArns:
- !Ref SnsPublishAccessPolicy
在评论部分让我知道你的想法。
推荐阅读
- c - 在 for 循环中中断 if 语句
- android - stopSelf() 是否保证服务停止(以及如何停止)?如果是这样,是否需要返回(以防 stopSelf 在内部调用)?
- haskell - 阅读 int 孤立地工作,但如何让它在这个脚本中工作?
- sql-server - SSIS Foreach 循环容器不循环通过 Excel 文件
- sql-server - 如何在 SQL 中为临时表创建标识列?
- ruby - 在 Lambda 中运行 ruby 时,“在任何来源中都找不到 public_suffix-3.0.2”
- lua - 如何获得佳能相机的相机角度?
- elasticsearch - 根据数组 ElasticSearch 中的项目过滤文档
- ruby-on-rails - 如何停止在重定向上发送预检请求?
- cakephp - 如何在 cakephp 3 中创建选项页面