0

我一直在使用 Terraform 在其中创建一个 AWS 组织和三个额外的帐户。

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
  cloud {
    hostname     = "app.terraform.io"
    organization = "MyOrg"

    workspaces {
      name = "MyWorkspace"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

resource "aws_organizations_organization" "organization" {
}

resource "aws_organizations_account" "users" {
  name      = "users"
  email     = "users@example.com"
  role_name = "Admin"
}

resource "aws_organizations_account" "staging" {
  name      = "staging"
  email     = "staging@example.com"
  role_name = "Admin"
}

resource "aws_organizations_account" "production" {
  name      = "production"
  email     = "production@example.com"
  role_name = "Admin"
}

provider "aws" {
  assume_role {
    role_arn = "arn:aws:iam::${aws_organizations_account.users.id}:role/Admin"
  }

  alias  = "users"
  region = var.aws_region
}

provider "aws" {
  assume_role {
    role_arn = "arn:aws:iam::${aws_organizations_account.users.id}:role/Admin"
  }

  alias  = "staging"
  region = var.aws_region
}

provider "aws" {
  assume_role {
    role_arn = "arn:aws:iam::${aws_organizations_account.users.id}:role/Admin"
  }

  alias  = "production"
  region = var.aws_region
}

resource "aws_iam_group" "self_managing" {
  name = "SelfManaging"

  provider = aws.users
}

resource "aws_iam_group_policy_attachment" "iam_read_only_access" {
  group      = aws_iam_group.self_managing.name
  policy_arn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"

  provider = aws.users
}

resource "aws_iam_group_policy_attachment" "iam_self_manage_service_specific_credentials" {
  group      = aws_iam_group.self_managing.name
  policy_arn = "arn:aws:iam::aws:policy/IAMSelfManageServiceSpecificCredentials"

  provider = aws.users
}

resource "aws_iam_group_policy_attachment" "iam_user_change_password" {
  group      = aws_iam_group.self_managing.name
  policy_arn = "arn:aws:iam::aws:policy/IAMUserChangePassword"

  provider = aws.users
}

resource "aws_iam_policy" "self_manage_vmfa" {
  name   = "SelfManageVMFA"
  policy = file("${path.module}/data/self_manage_vmfa.json")

  provider = aws.users
}

resource "aws_iam_group_policy_attachment" "self_manage_vmfa" {
  group      = aws_iam_group.self_managing.name
  policy_arn = aws_iam_policy.self_manage_vmfa.arn

  provider = aws.users
}

module "developer_role_staging" {
  source         = "./modules/developer-role"
  trusted_entity = "arn:aws:iam::${aws_organizations_account.users.id}:root"

  providers = {
    aws = aws.staging
  }
}

module "developer_role_production" {
  source         = "./modules/developer-role"
  trusted_entity = "arn:aws:iam::${aws_organizations_account.users.id}:root"

  providers = {
    aws = aws.production
  }
}

module "developer_group_staging" {
  source     = "./modules/developer-group"
  group_name = "DevelopersStaging"

  assume_role_arns = [
    module.developer_role_staging.role_arn,
  ]

  providers = {
    aws = aws.users
  }
}

module "developer_group_production" {
  source     = "./modules/developer-group"
  group_name = "DevelopersProduction"

  assume_role_arns = [
    module.developer_role_production.role_arn
  ]

  providers = {
    aws = aws.users
  }
}

我运行 Terraform 的用户没有完全正确的权限。组织和帐户已创建,但状态似乎不包含它们。如果我运行terraform apply,则表明它将添加它们。但是,一旦接受该计划,每个帐户都会出现以下错误:-

Error: Error waiting for account request (car-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx) to become available: EMAIL_ALREADY_EXISTS

我阅读了aws_organizations_account 资源的文档,其中状态我可以terraform import aws_organizations_account.my_org 111111111111用来将其导入状态。但是,当我运行时,我得到了几个:-

Error: Invalid provider configuration
│
│   on path-to\main.tf line 42:
│   42: provider "aws" {
│
│ The configuration for provider["registry.terraform.io/hashicorp/aws"].users depends on values that cannot be determined until apply.

我真的被困住了,希望能得到一些指点。

更新 根据要求,我添加了输出terraform plan

Terraform v1.1.0
on linux_amd64
Configuring remote state backend...    
Initializing Terraform configuration...
aws_organizations_organization.organization: Refreshing state... [id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # aws_iam_group.self_managing will be created
  + resource "aws_iam_group" "self_managing" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "SelfManaging"
      + path      = "/"
      + unique_id = (known after apply)
    }

  # aws_iam_group_policy_attachment.iam_read_only_access will be created
  + resource "aws_iam_group_policy_attachment" "iam_read_only_access" {
      + group      = "SelfManaging"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
    }

  # aws_iam_group_policy_attachment.iam_self_manage_service_specific_credentials will be created
  + resource "aws_iam_group_policy_attachment" "iam_self_manage_service_specific_credentials" {
      + group      = "SelfManaging"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/IAMSelfManageServiceSpecificCredentials"
    }

  # aws_iam_group_policy_attachment.iam_user_change_password will be created
  + resource "aws_iam_group_policy_attachment" "iam_user_change_password" {
      + group      = "SelfManaging"
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/IAMUserChangePassword"
    }

  # aws_iam_group_policy_attachment.self_manage_vmfa will be created
  + resource "aws_iam_group_policy_attachment" "self_manage_vmfa" {
      + group      = "SelfManaging"
      + id         = (known after apply)
      + policy_arn = (known after apply)
    }

  # aws_iam_policy.self_manage_vmfa will be created
  + resource "aws_iam_policy" "self_manage_vmfa" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "SelfManageVMFA"
      + path      = "/"
      + policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action   = [
                          + "iam:CreateVirtualMFADevice",
                          + "iam:EnableMFADevice",
                          + "iam:ResyncMFADevice",
                          + "iam:DeleteVirtualMFADevice",
                        ]
                      + Effect   = "Allow"
                      + Resource = [
                          + "arn:aws:iam::*:mfa/${aws:username}",
                          + "arn:aws:iam::*:user/${aws:username}",
                        ]
                    },
                  + {
                      + Action    = [
                          + "iam:DeactivateMFADevice",
                        ]
                      + Condition = {
                          + Bool = {
                              + aws:MultiFactorAuthPresent = "true"
                            }
                        }
                      + Effect    = "Allow"
                      + Resource  = [
                          + "arn:aws:iam::*:mfa/${aws:username}",
                          + "arn:aws:iam::*:user/${aws:username}",
                        ]
                      + Sid       = "AllowUsersToDeactivateTheirOwnVirtualMFADevice"
                    },
                  + {
                      + Action   = [
                          + "iam:ListMFADevices",
                          + "iam:ListVirtualMFADevices",
                          + "iam:ListUsers",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + policy_id = (known after apply)
      + tags_all  = (known after apply)
    }

  # aws_organizations_account.production will be created
  + resource "aws_organizations_account" "production" {
      + arn              = (known after apply)
      + email            = "production@example.com"
      + id               = (known after apply)
      + joined_method    = (known after apply)
      + joined_timestamp = (known after apply)
      + name             = "production"
      + parent_id        = (known after apply)
      + role_name        = "Admin"
      + status           = (known after apply)
      + tags_all         = (known after apply)
    }

  # aws_organizations_account.staging will be created
  + resource "aws_organizations_account" "staging" {
      + arn              = (known after apply)
      + email            = "staging@example.com"
      + id               = (known after apply)
      + joined_method    = (known after apply)
      + joined_timestamp = (known after apply)
      + name             = "staging"
      + parent_id        = (known after apply)
      + role_name        = "Admin"
      + status           = (known after apply)
      + tags_all         = (known after apply)
    }

  # aws_organizations_account.users will be created
  + resource "aws_organizations_account" "users" {
      + arn              = (known after apply)
      + email            = "users@example.com"
      + id               = (known after apply)
      + joined_method    = (known after apply)
      + joined_timestamp = (known after apply)
      + name             = "users"
      + parent_id        = (known after apply)
      + role_name        = "Admin"
      + status           = (known after apply)
      + tags_all         = (known after apply)
    }

  # module.developer_group_production.data.template_file.assume_role will be read during apply
  # (config refers to values not yet known)
 <= data "template_file" "assume_role"  {
      + id       = (known after apply)
      + rendered = (known after apply)
      + template = (known after apply)
    }

  # module.developer_group_production.aws_iam_group.this will be created
  + resource "aws_iam_group" "this" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "DevelopersProduction"
      + path      = "/"
      + unique_id = (known after apply)
    }

  # module.developer_group_production.aws_iam_group_policy_attachment.assume_role will be created
  + resource "aws_iam_group_policy_attachment" "assume_role" {
      + group      = "DevelopersProduction"
      + id         = (known after apply)
      + policy_arn = (known after apply)
    }

  # module.developer_group_production.aws_iam_policy.assume_role will be created
  + resource "aws_iam_policy" "assume_role" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "DevelopersProductionAssumeRole"
      + path      = "/"
      + policy    = (known after apply)
      + policy_id = (known after apply)
      + tags_all  = (known after apply)
    }

  # module.developer_group_staging.data.template_file.assume_role will be read during apply
  # (config refers to values not yet known)
 <= data "template_file" "assume_role"  {
      + id       = (known after apply)
      + rendered = (known after apply)
      + template = (known after apply)
    }

  # module.developer_group_staging.aws_iam_group.this will be created
  + resource "aws_iam_group" "this" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "DevelopersStaging"
      + path      = "/"
      + unique_id = (known after apply)
    }

  # module.developer_group_staging.aws_iam_group_policy_attachment.assume_role will be created
  + resource "aws_iam_group_policy_attachment" "assume_role" {
      + group      = "DevelopersStaging"
      + id         = (known after apply)
      + policy_arn = (known after apply)
    }

  # module.developer_group_staging.aws_iam_policy.assume_role will be created
  + resource "aws_iam_policy" "assume_role" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = "DevelopersStagingAssumeRole"
      + path      = "/"
      + policy    = (known after apply)
      + policy_id = (known after apply)
      + tags_all  = (known after apply)
    }

  # module.developer_role_production.data.template_file.trust_relationship will be read during apply
  # (config refers to values not yet known)
 <= data "template_file" "trust_relationship"  {
      + id       = (known after apply)
      + rendered = (known after apply)
      + template = (known after apply)
    }

  # module.developer_role_production.aws_iam_role.this will be created
  + resource "aws_iam_role" "this" {
      + arn                   = (known after apply)
      + assume_role_policy    = (known after apply)
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "Developer"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy {
          + name   = (known after apply)
          + policy = (known after apply)
        }
    }

  # module.developer_role_production.aws_iam_role_policy_attachment.administrator_access will be created
  + resource "aws_iam_role_policy_attachment" "administrator_access" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
      + role       = "Developer"
    }

  # module.developer_role_staging.data.template_file.trust_relationship will be read during apply
  # (config refers to values not yet known)
 <= data "template_file" "trust_relationship"  {
      + id       = (known after apply)
      + rendered = (known after apply)
      + template = (known after apply)
    }

  # module.developer_role_staging.aws_iam_role.this will be created
  + resource "aws_iam_role" "this" {
      + arn                   = (known after apply)
      + assume_role_policy    = (known after apply)
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "Developer"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy {
          + name   = (known after apply)
          + policy = (known after apply)
        }
    }

  # module.developer_role_staging.aws_iam_role_policy_attachment.administrator_access will be created
  + resource "aws_iam_role_policy_attachment" "administrator_access" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
      + role       = "Developer"
    }
4

0 回答 0