【问题标题】:Terraform policy attachment to a role name in moduleTerraform 策略附加到模块中的角色名称
【发布时间】:2019-04-02 16:22:57
【问题描述】:

我正在尝试使用 Terraform 在 AWS 的三个环境中创建数据角色。 一个是 root 帐户中的角色。此角色可用于登录 AWS,并可在生产和暂存中担任数据角色。这工作正常。这是使用单独的模块。

我在尝试从模块创建 prod 和 staging 角色时遇到问题。 我的模块看起来像这样 main.tf:

resource "aws_iam_role" "this" {

  name               = "${var.name}"
  description        = "${format("%s (managed by Terraform)", var.policy_description)}"
  assume_role_policy = "${length(var.custom_principals) == 0 ? data.aws_iam_policy_document.assume_role.json : data.aws_iam_policy_document.assume_role_custom_principals.json}"
}

resource "aws_iam_policy" "this" {
  name        = "${var.name}"
  description = "${format("%s (managed by Terraform)", var.policy_description)}"
  policy      = "${var.policy}"
}

data "aws_iam_policy_document" "assume_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${var.account_id}:root"]
    }
  }
}

data "aws_iam_policy_document" "assume_role_custom_principals" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type = "AWS"

      identifiers = [
        "${var.custom_principals}",
      ]
    }
  }
}

resource "aws_iam_role_policy_attachment" "this" {
  role       = "${aws_iam_role.this.name}"
  policy_arn = "${aws_iam_policy.this.arn}"
}

我在 output.tf 中也有以下内容:

output "role_name" {
   value = "${aws_iam_role.this.name}"
}

接下来我尝试使用该模块在 prod 和 staging 中创建两个角色。 main.tf:

module "data_role" {
  source = "../tf_data_role"

  account_id         = "${var.account_id}"
  name               = "data"
  policy_description = "Role for data engineers"

  custom_principals = [
    "arn:aws:iam::${var.master_account_id}:root",
  ]

  policy = "${data.aws_iam_policy_document.data_access.json}"
}

然后我尝试附加这样的 AWS 策略:

resource "aws_iam_role_policy_attachment" "data_readonly_access" {
  role       = "${module.data_role.role_name}"
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

resource "aws_iam_role_policy_attachment" "data_redshift_full_access" {
  role       = "${module.data_role.role_name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonRedshiftFullAccess"
}

我在这里遇到的问题是,当我尝试运行此模块时,上述两个策略未附加在暂存中,而是附加在 root 帐户中。如何解决此问题以使其附加暂存策略?

【问题讨论】:

    标签: amazon-web-services terraform


    【解决方案1】:

    我会根据您的问题假设 staging 是它自己的 AWS 账户,与您的根账户分开。 From the Terraform docs

    您可以为同一个提供者定义多个配置,以支持多个区域、多个主机等。

    这也适用于在多个 AWS 账户中创建资源。要在两个 AWS 账户中创建 Terraform 资源,请按照以下步骤操作。

    在您的入口点 main.tf 中,为您要定位的帐户定义 aws providers

    # your normal provider targeting your root account
    provider "aws" {
      version = "1.40"
      region = "us-east-1"
    }
    
    provider "aws" {
      version = "1.40"
      region = "us-east-1"
    
      alias = "staging" # define custom alias
    
      # either use an assumed role or allowed_account_ids to target another account
      assume_role {
        role_arn = "arn:aws:iam:STAGINGACCOUNTNUMBER:role/Staging"
      }
    }
    

    (注意:角色 arn 必须已经存在,并且您当前的 AWS 凭证必须具有代入该角色的权限)

    use them in your module,像这样调用你的模块

    module "data_role" {
      source = "../tf_data_role"
    
      providers = {
        aws.staging = "aws.staging"
        aws = "aws"
      }
    
      account_id         = "${var.account_id}"
      name               = "data"
    
      ... remainder of module
    }
    

    并像这样在您的模块中定义提供程序

    provider "aws" {
      alias = "staging"
    }
    
    provider "aws" {}
    

    现在,当您在模块中声明资源时,您可以指定在哪个 AWS 提供商(以及因此哪个账户)中创建资源,例如

    resource "aws_iam_role" "this" {
      provider = "aws.staging"  # this aws_iam_role will be created in your staging account
    
      name               = "${var.name}"
      description        = "${format("%s (managed by Terraform)", var.policy_description)}"
      assume_role_policy = "${length(var.custom_principals) == 0 ? data.aws_iam_policy_document.assume_role.json : data.aws_iam_policy_document.assume_role_custom_principals.json}"
    }
    
    resource "aws_iam_policy" "this" {
      # no explicit provider is set here so it will use the "default" (un-aliased) aws provider and create this aws_iam_policy in your root account
      name        = "${var.name}"
      description = "${format("%s (managed by Terraform)", var.policy_description)}"
      policy      = "${var.policy}"
    }
    

    【讨论】:

    • 您好 rwisch45,感谢您的帮助。我试图避免这样做,因为它会破坏我们迄今为止所写的一切。我将暂时推迟这样做,我们整个团队将讨论如何解决这个问题。再次感谢。
    猜你喜欢
    • 2020-10-31
    • 1970-01-01
    • 2017-05-17
    • 2017-12-13
    • 2021-04-29
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多