如何将角色的名称/ ARN纳入其自己的AssumeRole策略?

时间:2020-10-06 23:27:29

标签: amazon-web-services amazon-cloudformation

我有一个CloudFormation堆栈,该堆栈创建了多个IAM角色。我有一个听起来有些不寻常的要求,要在角色的AssumeRole策略中包含一条语句,以防止该角色扮演自己。角色名称是使用带有参数值的Fn::Join构造的,因此,为了重现角色名称并在策略语句中构造其ARN,我必须复制该表达式。

有什么方法可以缓存表达式的结果,这样我就不必重复它了?这些角色有几种,每个角色都有相同的问题。我可以定义一个参数的默认值包括另一个参数的值并引用该参数吗?还是可以在资源的定义内使用Fn:GetAtt来访问正在定义的资源的其他属性(例如其名称)?

如果没有,除了重复名称构造表达式之外,还有其他解决方案吗?这是我要放在Terraform的locals块中的内容...

由于无法完成此任务,因此我创建了此外壳一线式脚本以在创建后更新每个角色,以防止其扮演自己的角色:

aws iam update-assume-role-policy \
  --role-name "$role" \
  --policy-document file://<(
      aws iam get-role --role-name "$role" |
       jq '.Role | .Arn as $arn | .AssumeRolePolicyDocument | 
           .Statement+=[{"Effect": "Deny", 
                         "Action": "sts:AssumeRole", 
                         "Principal": { "AWS": $arn }}]')

1 个答案:

答案 0 :(得分:1)

有什么方法可以缓存表达式的结果,这样我就不必重复它了?

不幸的是,普通的CloudFormation中没有这种方法。

我可以定义一个默认值包含另一个参数值的参数并引用该参数吗?

不幸的是,参数不能引用其他参数。

还是可以在资源定义内使用Fn:GetAtt来访问正在定义的资源的其他属性(例如其名称)?

在资源完全构建之前,您无法获得任何返回值。

很遗憾,如果您事先知道角色名称,则可以自己构建其ARN。角色ARN具有known format。但是,您希望能够以相同的角色将其用作Principal,因为原理必须有效。因此,您不能在角色实际存在之前就将其用作角色。

如果要将角色的ARN添加为自己的角色Principal,则必须在CloudFormation中构造一个custom resource。因此,您首先要正常创建角色,然后使用自定义资源(以lambda函数的形式)来更新其Principal元素。

此外,由于必须在模板中复制很多元素,因此一般的解决方案是使用CloudFormation macros

无论哪种方式,在我看来,由于通常不立即支持您对模板的要求,因此您将必须开发一些自定义资源和/或宏来完全满足它们。使用自定义资源和宏,您基本上可以实现所需的功能,但这需要额外的开发。