使用 CircleCI 在 AWS 上部署 - OpenID Connect
我们在部署配置期间做的第一件事就是为 CI/CD 工具创建凭据。
对于 AWS,最简单的方法是使用编程密钥创建 IAM 用户。它们被放入 CI/CD 工具内部的机密或环境变量中,分别为:AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY。它被称为长期凭证,因为默认情况下没有过期时间。我们必须自己轮换它们。
另一种更安全的方法是使用短期凭证,它会在特定时间后自动失效。
在本文中,我将介绍使用 *OpenID Connect 协议、CircleCI 作为部署平台和 AWS 作为目标的示例解决方案。我不会深入研究协议细节。
主要思想概述
这是一个简化的图表,显示了整个过程的样子。
[
](https://res.cloudinary.com/practicaldev/image/fetch/s---XwA06Ts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to -uploads.s3.amazonaws.com/uploads/articles/0plb3x33m7zenn320rhv.png)
我们需要在 AWS 中授权两件事:
-
OIDC 令牌
-
AWS IAM 角色
OIDC Token 将由 CircleCI 生成,但 IAM Role 需要由我们创建。
Terraform - 创建 IAM 角色和 OIDC 提供程序
main.tf - 很常见。无需说明
terraform {
required_version = "1.1.4"
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.8.0"
}
}
}
provider "aws" {
region = "eu-central-1"
}
进入全屏模式 退出全屏模式
变量.tf
我们需要 3 个值来在 AWS 中配置我们的 IAM 角色和 OIDC 提供者资源。circleci_org_id和circleci_thumbprint用于创建 OIDC Provider,它们对于我们的目的来说是相当静态的(我们在同一个 CircleCI 组织中有多个存储库/CircleCI 项目)。
circleci_project_id允许我们将 IAM 角色限制为特定项目。我们希望从特定(一个或多个)项目而不是整个组织向 AWS 授权。
variable "circleci_org_id" {
default = "CHANGE_ME"
description = "CircleCI Organization ID"
}
variable "circleci_thumbprint" {
# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
default = "CHANGE_ME"
description = "Fingerprint of CircleCI servers"
}
variable "circleci_project_id" {
default = "CHANGE_ME"
description = "CircleCI Project ID"
}
进入全屏模式 退出全屏模式
oidc.tf
最重要的部分。我们有 OIDC 提供者和 IAM 角色以及联合主体和 2 个条件。它们与来自 OIDC 令牌的值进行比较。第二个条件包含架构:
"org/${var.circleci_org_id}/project/${var.circleci_project_id}/user/*"
进入全屏模式 退出全屏模式
这意味着,对特定 CircleCI 组织中的特定 CircleCI 项目具有权限的所有用户都能够成功运行此管道。整个配置与连接到 CircleCI 的 Github 平台一起使用,因此 Github 管理权限。
最后,我们将其他权限附加到角色。
resource "aws_iam_openid_connect_provider" "default" {
url = "https://oidc.circleci.com/org/${var.circleci_org_id}"
client_id_list = [var.circleci_org_id]
thumbprint_list = [var.circleci_thumbprint]
}
###########################################################
data "aws_caller_identity" "current" {}
data "aws_iam_policy_document" "circleci" {
statement {
actions = ["sts:AssumeRoleWithWebIdentity", "sts:TagSession"]
principals {
type = "Federated"
identifiers = [
"${aws_iam_openid_connect_provider.default.arn}"
]
}
condition {
test = "StringEquals"
variable = "oidc.circleci.com/org/${var.circleci_org_id}:aud"
values = [var.circleci_org_id]
}
condition {
test = "ForAnyValue:StringLike"
variable = "oidc.circleci.com/org/${var.circleci_org_id}:sub"
values = ["org/${var.circleci_org_id}/project/${var.circleci_project_id}/user/*"]
}
}
}
resource "aws_iam_role" "circleci" {
name = "circleci"
path = "/"
assume_role_policy = data.aws_iam_policy_document.circleci.json
}
resource "aws_iam_role_policy_attachment" "attach_1" {
role = aws_iam_role.circleci.name
policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}
进入全屏模式 退出全屏模式
CircleCI配置
.circleci/config.yml
version: 2.1
orbs:
aws-cli: circleci/aws-cli@3.0.0
commands:
aws-oidc-setup:
description: Setup AWS auth using OIDC token
parameters:
aws-role-arn:
type: string
steps:
- run:
name: Get short-term credentials
command: |
STS=($(aws sts assume-role-with-web-identity --role-arn << parameters.aws-role-arn >> --role-session-name "${CIRCLE_BRANCH}-${CIRCLE_BUILD_NUM}" --web-identity-token "${CIRCLE_OIDC_TOKEN}" --duration-seconds 900 --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' --output text))
echo "export AWS_ACCESS_KEY_ID=${STS[0]}" >> $BASH_ENV
echo "export AWS_SECRET_ACCESS_KEY=${STS[1]}" >> $BASH_ENV
echo "export AWS_SESSION_TOKEN=${STS[2]}" >> $BASH_ENV
- run:
name: Verify AWS credentials
command: aws sts get-caller-identity
jobs:
test:
executor: aws-cli/default
steps:
- checkout
- aws-cli/install
- aws-oidc-setup:
aws-role-arn: "arn:aws:iam::XXXXXXXXXXXX:role/circleci"
- run:
name: Test AWS connection
command: aws s3 ls
workflows:
build_and_deploy:
jobs:
- test:
context:
- example-context
进入全屏模式 退出全屏模式
在这里,我们使用用于在 AWS 中授权的自定义命令进行配置。有几件重要的事情:
-
parameters.aws-role-arn-> 之前创建的 IAM 角色 -
role-session-name-> 可以是任何东西。它将在 AWS CloudTrail 中显示为user字段 -
CIRCLE_OIDC_TOKEN-> 它是 OIDC 令牌。如果作业使用任何上下文,它由 CircleCI 仅添加。这就是我在工作流程中添加example-context的原因。此上下文也可以为空。 -
duration-seconds- 令牌有效时间
您可以在作业中使用 SSH 检查CIRCLE_OIDC_TOKEN内部的内容,并在此处对其进行解码:jwt.io
circleci@a094c7852509:~$ echo $CIRCLE_OIDC_TOKEN
eyJraWQiOiJhSzlqNmRZQm8zS0R3NGdmV3k4eGRNTFU1UThPeWNzcW44S.......
进入全屏模式 退出全屏模式
文档
-
https://circleci.com/docs/2.0/openid-connect-tokens/
-
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
这是我的第一篇文章,所以欢迎反馈:)
更多推荐

所有评论(0)