【问题标题】:How to get an AWS role's friendly name from its ARN?如何从其 ARN 中获取 AWS 角色的友好名称?
【发布时间】:2022-03-12 14:47:51
【问题描述】:

我正在尝试将策略附加到 Terraform 中的 IAM 角色。我只知道角色的 ARN 编号,而不知道它的“友好名称”。但策略附件功能要求我使用友好名称,而不是 ARN 编号。

如果我已经拥有 ARN 编号,如何获取 IAM 角色的友好名称?

这是我目前所拥有的——它给了我“ValidationError:角色名称的指定值无效。它必须只包含字母数字字符和/或以下内容:+=,.@_-”。我相信这是因为我使用的是角色名称的 ARN 编号而不是友好的角色名称。

resource "aws_iam_role_policy_attachment" "my-policy-attachment" {
  role       = "arn:aws:iam::my_user_account_id:role/my_role_name"
  policy_arn = aws_iam_policy.my_policy.arn
}

谢谢!

【问题讨论】:

  • 你试过“my_role_name”吗?

标签: amazon-web-services terraform


【解决方案1】:

“友好名称”只是 ARN 的最后一部分。

所以对于arn:aws:iam::my_user_account_id:role/my_role_name,友好名称将是my_role_name。您可以像这样使用 split 天真地使用 Terraform 来解决这个问题:

resource "aws_iam_role_policy_attachment" "my-policy-attachment" {
  role       = split("/", "arn:aws:iam::my_user_account_id:role/my_role_name")[1]
  policy_arn = aws_iam_policy.my_policy.arn
}

或者,也许更好,像这样:

variable "role_arn" {}

locals {
  role_friendly_name = split("/", var.role_arn)[1]
}

resource "aws_iam_role_policy_attachment" "my-policy-attachment" {
  role       = local.role_friendly_name
  policy_arn = aws_iam_policy.my_policy.arn
}

这适用于这种情况,但您可能还需要考虑其中也有路径前缀的角色。然后,这将为您提供一个看起来更像 arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole 的 ARN,因此上面将返回 service-role

在某些语言中,您可以使用负索引来访问列表末尾的内容,但 Terraform/HCL2 目前不允许这样做(请参阅this feature request)。因此,我们还需要使用length function

variable "role_arn" {}

locals {
  role_split = split("/", var.role_arn)[1]
  role_friendly_name = local.role_split[length(local.role_split) - 1]
}

resource "aws_iam_role_policy_attachment" "my-policy-attachment" {
  role       = local.role_friendly_name
  policy_arn = aws_iam_policy.my_policy.arn
}

【讨论】:

  • 太棒了!谢谢@ydaetskcoR :) 不知道为什么我在 AWS 文档中找不到它:P
  • 需要明确的是,如果我们有一个看起来像“arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole”的 ARN,友好名称是否会是“AWSBackupDefaultServiceRole”?还是“服务角色/AWSBackupDefaultServiceRole”?
  • 应该是AWSBackupDefaultServiceRoleservice-role 将是路径前缀。从/ 分隔列表中选择最后一个元素将始终有效,因为名称本身不能包含/,正如您从AWS API documentation 中看到的那样
【解决方案2】:
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn#resource

data "aws_arn" "ecs_role" {
  arn = aws_iam_role.ecs_task_role.arn
}

上面的示例 arn 是 = arn:aws:iam:abc:role/app/task/ecs_task_role

# https://www.terraform.io/language/functions/trimprefix

locals {
  ecs_task_role_name = trimprefix(data.aws_arn.ecs_role.resource, "role/")
}

data.aws_arn_ecs_role.resource 将解析为:role/app/task/ecs_task_role。 现在 trimprefix 可用于将 role 从数据输出中拆分出来。

【讨论】:

    【解决方案3】:

    还可以使用 trimprefix 等功能。在这种情况下,有助于从 arn 获取负载均衡器名称。

    load_balancer_arn = "arn:aws:elasticloadbalancing:us-east-1:xxxxx:loadbalancer/app/awseb-AWSEB-xxxx/xxxxxx"
    
    locals {
      arn_split          = split("/", var.load_balancer_arn)
      load_balancer_name = trimprefix(trimprefix(var.load_balancer_arn, local.arn_split[0]), "/")
    }
    
    returns "app/awseb-AWSEB-xxxx/xxxxxx"
    

    【讨论】:

      猜你喜欢
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2019-01-03
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多