如何在不使用密钥的情况下将 GitHub 操作与 AWS 部署连接? [英] How can I connect GitHub actions with AWS deployments without using a secret key?

查看:40
本文介绍了如何在不使用密钥的情况下将 GitHub 操作与 AWS 部署连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够使用 GitHub Actions 来使用 AWS 部署资源,但无需使用硬编码用户.

I'd like to be able to use GitHub Actions to be able to deploy resources with AWS, but without using a hard-coded user.

我知道可以创建具有固定凭据的 IAM 用户,并且可以将其导出到 GitHub Secrets,但这意味着如果密钥泄露,我手头会有很大的问题,而轮换此类密钥具有挑战性如果忘记了.

I know that it's possible to create an IAM user with a fixed credential, and that can be exported to GitHub Secrets, but this means if the key ever leaks I have a large problem on my hands, and rotating such keys are challenging if forgotten.

有什么方法可以启用无密码身份验证流程以将代码部署到 AWS?

Is there any way that I can enable a password-less authentication flow for deploying code to AWS?

推荐答案

是的,现在 GitHub 已经发布了他们的 开放 ID 连接器用于 GitHub 操作.您可以将 Open ID 连接器配置为 AWS 中的身份提供者,然后将其用作您希望启用的任何角色的访问点.然后,您可以将操作配置为使用在作业期间获取的凭据,当作业完成时,凭据会自动撤销.

Yes, it is possible now that GitHub have released their Open ID Connector for use with GitHub Actions. You can configure the Open ID Connector as an Identity Provider in AWS, and then use that for an access point to any role(s) that you wish to enable. You can then configure the action to use the credentials acquired for the duration of the job, and when the job is complete, the credentials are automatically revoked.

要在 AWS 中进行设置,您需要使用 AWS 上的说明 或使用类似于以下的 Terraform 文件:

To set this up in AWS, you need to create an Open Identity Connect Provider using the instructions at AWS or using a Terraform file similar to the following:

resource "aws_iam_openid_connect_provider" "github" {
  url = "https://token.actions.githubusercontent.com"
  client_id_list = [
    "sigstore",           // GitHub's default
    "sts.amazonaws.com",  // Proposal for aws-actions/configure-aws-credentials
  ]
  thumbprint_list = [
    "a031c46782e6e6c662c2c87c76da9aa62ccabd8e",
    "6938fd4d98bab03faadb97b34396831e3780aea1",
  ]
}

客户 ID 列表是用于访问此内容的受众"——您可以对其进行更改,前提是您在所有正确的位置进行更改.指纹是 Open ID 连接器的哈希/证书,a031...bd8e 是 GitHub Actions 当前使用的指纹——您可以通过 遵循 AWS 的说明.thumbprint_list 最多可以保存 5 个值,因此可以在提前提供新版本时附加这些值,同时继续使用旧版本.

The client id list is the 'audience' which is used to access this content -- you can vary that, provided that you vary it in all the right places. The thumbprint is a hash/certificate of the Open ID Connector, and a031...bd8e is the current one used by GitHub Actions -- you can calculate/verify the value by following AWS' instructions. The thumbprint_list can hold up to 5 values, so newer versions can be appended when they are being made available ahead of time while continuing to use older ones.

如果您对这个神奇值的来源感兴趣,可以在 如何计算 OpenID Connect 服务器的指纹?

If you're interested in where this magic value came from, you can find out at How can I calculate the thumbprint of an OpenID Connect server?

启用身份提供者后,您可以使用它来创建一个或多个自定义角色(替换为:

Once you have enabled the identity provider, you can use it to create one or more custom roles (replacing with :

data "aws_caller_identity" "current" {}
resource "aws_iam_role" "github_alblue" {
  name = "GitHubAlBlue"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Action = "sts:AssumeRoleWithWebIdentity"
      Effect = "Allow"
      Principal = {
        Federated = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/token.actions.githubusercontent.com"
      }
      Condition = {
        StringLike = {
          "token.actions.githubusercontent.com:aud" :  ["sigstore", "sts.amazonaws.com ],
          "token.actions.githubusercontent.com:sub" : "repo:alblue/*"
        }
      }
    }]
  })
}

您可以根据需要创建任意数量的不同角色,甚至可以按受众(例如生产"、开发")将它们分开.如果该帐户信任 OpenID 连接器的受众,那么您就可以开始了.(您可以使用它来确保开发帐户中的 OpenID 连接器不信任生产帐户中的角色,反之亦然.)例如,您可以拥有一个只读角色来执行 terraform validate 然后是 terraform apply 的另一个角色.

You can create as many different roles as you need, and even split them up by audience (e.g. 'production', 'dev'). Provided that the OpenID connector's audience is trusted by the account then you're good to go. (You can use this to ensure that the OpenID Connector in a Dev account doesn't trust the roles in a production account and vice-versa.) You can have, for example, a read-only role for performing terraform validate and then another role for terraform apply.

主题是从 GitHub 传递的,但看起来像:

The subject is passed from GitHub, but looks like:

repo:<organization>/<repository>:ref:refs/heads/<branch>

以后可能会出现不同的格式.例如,如果您使用 :ref:refs/pulls/*,您可以有一个专门针对 PR 的操作/角色,并有另一个角色用于 :ref:refs/heads/production/*.

There may be different formats that come out later. You could have an action/role specifically for PRs if you use :ref:refs/pulls/* for example, and have another role for :ref:refs/heads/production/*.

最后一步是将您的 GitHub Actions 配置为使用从 AWS/OpenID Connect 返回的令牌:

The final step is getting your GitHub Actions configured to use the token that comes back from the AWS/OpenID Connect:

标准方式

jobs:
  terraform-validate:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Configure AWS credentials from Test account
        uses: aws-actions/configure-aws-credentials@master
        with:
          role-to-assume: arn:aws:iam::<accountid>:role/GitHubAlBlue
          aws-region: us-east-1
          audience: sigstore
      - name: Display Identity
        run: aws sts get-caller-identity

手动方式

幕后实际发生的事情是这样的:

What's actually happening under the covers is something like this:

jobs:
  terraform-validate:
    runs-on: ubuntu-latest
    env:
      AWS_WEB_IDENTITY_TOKEN_FILE: .git/aws.web.identity.token.file
      AWS_DEFAULT_REGION: eu-west-2
      AWS_ROLE_ARN: arn:aws:iam::<accountid>:role/GitHubAlBlue
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Configure AWS
        run: |
          sleep 3 # Need to have a delay to acquire this
          curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" 
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sigstore" 
            | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE
          aws sts get-caller-identity

您需要确保您的 AWS_ROLE_ARN 与您的 AWS 账户中定义的相同,并且受众与 OpenID Connect 和角色名称所接受的受众相同.

You need to ensure that your AWS_ROLE_ARN is the same as defined in your AWS account, and that the audience is the same as accepted by the OpenID Connect and the Role name as well.

本质上,作业开始与令牌的有效性之间存在竞争条件,直到 GitHub 确认作业已开始后才会生效;如果 AWS_WEB_IDENITY_TOKEN_FILE 的大小小于 10 个字符,则可能是一个错误,然后 sleep/spinning 将为您获取值.

Essentially, there's a race condition between the job starting, and the token's validity which doesn't come in until after GitHub has confirmed the job has started; if the size of the AWS_WEB_IDENITY_TOKEN_FILE is less than 10 chars, it's probably an error and sleep/spinning will get you the value afterwards.

AWS_WEB_IDENTITY_TOKEN_FILE 的名称并不重要,只要一致即可.如果您使用的是 docker 容器,则将其存储在例如/tmp 意味着它在任何正在运行的容器中都不可用.如果您将它放在工作区中的 .git 下,那么 git 不仅会忽略它(如果您正在执行任何哈希计算),而且它还会出现在您执行的任何其他 docker run 操作中稍后.

The name of the AWS_WEB_IDENTITY_TOKEN_FILE doesn't really matter, so long as it's consistent. If you're using docker containers, then storing it in e.g. /tmp will mean that it's not available in any running containers. If you put it under .git in the workspace, then not only will git ignore it (if you're doing any hash calculations) but it will also be present in any other docker run actions that you do later on.

您可能希望配置您的角色,以限制所用期限的有效性;一旦您拥有 Web 令牌,它在作业结束前一直有效,但所请求的令牌的生命周期为 15 分钟,因此运行时间较长的作业可能会暴露它.

You might want to configure your role so that the validity of the period used is limited; once you have the web token it's valid until the end of the job, but the token requested has a lifetime of 15 minutes, so it's possible for a longer-running job to expose that.

GitHub 很可能会在不久的将来发布一篇关于如何配置/使用它的博文.以上信息的灵感来自 https://awsteele.com/blog/2021/09/15/aws-federation-comes-to-github-actions.html,如果您喜欢的话,谁在 CloudFormation 模板中提供了一些示例.

It's likely that GitHub will have a blog post on how to configure/use this in the near future. The above information was inspired by https://awsteele.com/blog/2021/09/15/aws-federation-comes-to-github-actions.html, who has some examples in CloudFormation templates if that's your preferred thing.

更新 GitHub(意外)更改了他们的指纹,示例已更新.有关更多信息,请参阅.新的指纹是 6938fd4d98bab03faadb97b34396831e3780aea1,但 IAM OpenID 连接器中可以有多个指纹.

Update GitHub (accidentally) changed their thumbprint and the example has been updated. See for more information. The new thumbprint is 6938fd4d98bab03faadb97b34396831e3780aea1 but it's possible to have multiple thumbprints in the IAM OpenID connector.

这篇关于如何在不使用密钥的情况下将 GitHub 操作与 AWS 部署连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆