【问题标题】:How to tell teamcity agent, which aws account to run terraform to如何告诉teamcity代理,哪个aws帐户运行terraform
【发布时间】:2020-09-15 18:38:42
【问题描述】:

我将 TeamCity 构建为 Kubernetes 集群。我有一个用于 TeamCity 服务器的部署和一个用于 TeamCity 构建代理的部署。当我在 TeamCity 构建代理上运行 Terraform 时,它会在与托管 TeamCity Kubernetes 集群的 EC2 实例相同的 AWS 账户中创建资源。

我想运行一个构建,它在单独的 AWS 账户中创建 AWS 资源。我的想法是为 TeamCity 服务器分配一个 AWS 访问密钥和秘密密钥,并将它们传递给 TeamCity 构建代理,但我不知道工作流程将如何。

目前,我已将 AWS 访问密钥和秘密密钥声明为构建中的环境变量,但它们没有传递给代理。我的构建步骤只包含 3 行

terraform init
terraform plan
terraform apply -auto-approve

【问题讨论】:

    标签: amazon-web-services kubernetes teamcity


    【解决方案1】:

    我处理过一个非常相似的情况。当我们开始使用 AWS 时,我们没有遵循关于我们的脚本如何向 AWS 进行身份验证的最佳实践。

    我们在每个帐户中创建了用户,并将访问和密钥导出到我们的 TeamCity 构建自动化中,以允许我们的脚本在这些帐户的上下文中运行。

    您将在不同帐户中拥有多个用户,并最终为这些用户手动轮换密钥,然后在每次需要轮换密钥时更新 TeamCity 中的访问密钥和秘密密钥。

    由于 TeamCity 构建代理服务器是 EC2 实例,因此在这种情况下,AWS 的最佳实践是使用角色而不是用户。来自 AWS 文档:

    在 Amazon EC2 实例上运行的应用程序需要在 为了访问其他 AWS 服务。向 以安全的方式应用程序,使用 IAM 角色。角色是一个实体 有自己的一组权限,但那不是用户或组。角色 也没有像 IAM 那样拥有自己的永久凭证集 用户做。对于 Amazon EC2,IAM 动态提供 EC2 实例的临时凭证,这些凭证是 自动为您旋转。

    来源:https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#use-roles-with-ec2

    在这种情况下您应该做的是在每个有权创建 terraform 将构建的资源的帐户中创建一个角色。您将需要另一个角色用于 TeamCity 构建代理服务器,该角色应该能够承担在每个帐户中创建的角色。

    假设您有两个帐户:

    1. AccountA 是您希望构建代理使用 terraform 运行构建资源的位置。
    2. AccountB 是运行构建代理的帐户。

    你需要的是:

    1. AccountA 中有权创建资源的角色。
    2. AccountB 中的一个角色,授予 ec2 实例访问权限以担任上述角色。

    AccountB 中角色的实例配置文件应分配给 TeamCity 构建代理服务器。然后,构建代理服务器能够承担 AccountA 中的角色,并在该帐户的上下文中以所需的权限运行,而无需硬编码的访问权限和密钥。

    您可以对任意数量的其他帐户重复此过程,以通过 Terraform 构建资源。

    您必须在 terraform 脚本中将以下块添加到 aws 提供程序,以让 terraform 知道要承担什么角色:

    provider "aws" {
    assume_role {
    role_arn = "arn:aws:iam::<ACCOUNTA>:role/<ROLENAME>"
    }
    }
    

    以下是有关如何授予对与 EC2 实例不同的账户中的 S3 存储桶的访问权限的一些 AWS 文档: https://aws.amazon.com/premiumsupport/knowledge-center/s3-instance-access-bucket/

    另一个有用的文档页面包括 IAM Roes、EC2 实例配置文件和通过角色进行跨账户访问: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html

    最后一个链接正是您想要做的事情: https://blog.e-zest.com/aws-ec2-assume-role-with-terraform

    【讨论】:

    • 非常感谢您回复 bak,在第一个实例中,我实际上使用的是 iam 角色,该角色分配给正在运行代理的 pod,所以您说我应该创建另一个代理和另一个将为目标 aws 帐户承担哪个角色?如果是这样的话,那么我想我不适合关闭,我不需要在 Teamcity 中做任何事情
    • 目前在我分配给 pod 的角色的帮助下,在 aws 帐户中创建了正确的资源,我认为这是因为我的代理在 aws 帐户的同一节点上,这可能就是原因,但是不,我想我将不得不从另一个 aws 帐户创建一个信任策略并将其分配给我的代理?让我知道我是否在正确的方向上实现这一目标
    • 您不需要创建另一个代理。您需要另一个帐户中的另一个角色,并允许分配给代理的角色代入另一个帐户中的角色。然后,您只需要告诉 Terraform 脚本要承担哪个角色,以便它知道要在哪个帐户中运行。我的答案中的这个页面显示了如何处理信任策略
    • 嗨,您的回答非常有道理,我通过在另一个帐户中创建角色并将该角色分配给代理来尝试上述步骤,它确实在另一个帐户中创建了资源。然而,混乱出现了,如果我正在创建具有所需权限的 s3 角色并将其分配给代理,那么我不应该在 terraform 提供程序文件中分配此角色,因为代理无论如何都有权限做事,我可以为代理分配多个角色吗?如果我有超过 1 个目标帐户,k8s 中的注释是否支持角色列表?/请你回答这两个问题,最后一点我卡住了
    • 在我们标记答案之前的最后一个问题,如果您能指导我如何将访问密钥和秘密访问密钥从 teamcity 传递到在 kubernetes pod 中运行的代理,我也想尝试一下,正是您在组织中使用的方式,目前我将这些分配为 env 变量,我只是不知道如何将这些值传递给代理,它应该在命令行上,还是在 pod yaml 文件中有一个目标变量将接受这些值
    【解决方案2】:

    当我想为 2 个单独的帐户添加两个注释时,我的 agent.yml 文件如下所示

    规格: 复制品:1 选择器: 匹配标签: 应用程序:代理-pod 模板: 元数据: 注释: iam.amazonaws.com/role: arn:aws:iam::account:role/accoun1-s3-role iam.amazonaws.com/role: arn:aws:iam::account:role/account2-pods-s3-role

    但是一旦我放了两个注释,我的 sts 承担 pod 的角色只向我展示了第二个角色。当我从 teamcity 运行构建时,我得到了这个错误 未找到适用于 aws 提供程序的有效凭据来源

    【讨论】:

      猜你喜欢
      • 2020-12-06
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      相关资源
      最近更新 更多