CircleCI를 사용하여 AWS에 배포 - OpenID Connect
AWS의 경우 가장 간단한 방법은 프로그래밍 방식 키로 IAM 사용자를 생성하는 것입니다. CI/CD 도구 내부의 비밀 또는 환경 변수에
AWS_ACCESS_KEY_ID
및 AWS_SECRET_ACCESS_KEY
로 배치됩니다. 기본적으로 만료 시간이 없기 때문에 장기 자격 증명이라고 합니다. 직접 회전시켜야 합니다.더 안전한 다른 방법은 특정 시간이 지나면 자동으로 무효화되는 단기 자격 증명을 사용하는 것입니다.
이 기사에서는 *OpenID Connect 프로토콜, CircleCI를 배포 플랫폼으로, AWS를 대상으로 사용하는 예제 솔루션을 제시합니다. 프로토콜 세부 사항에 대해서는 다루지 않겠습니다.
주요 아이디어 개요
이것은 전체 프로세스가 어떻게 보이는지 보여주는 단순화된 다이어그램입니다.
AWS에서 승인하려면 2가지가 필요합니다.
OIDC 토큰은 CircleCI에서 생성하지만 IAM 역할은 당사에서 생성해야 합니다.
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
AWS에서 IAM 역할 및 OIDC 공급자 리소스를 구성하려면 3개의 값이 필요합니다. circleci_org_id
및 circleci_thumbprint
는 OIDC 공급자를 생성하는 데 사용되며 우리 목적에 다소 정적입니다(동일한 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
가장 중요한 부분. 연합 보안 주체와 2가지 조건이 있는 OIDC 공급자 및 IAM 역할이 있습니다. 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/[email protected]
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에서 권한을 부여하는 데 사용되는 사용자 지정 명령이 포함된 구성이 있습니다. 몇 가지 중요한 사항이 있습니다.
terraform {
required_version = "1.1.4"
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.8.0"
}
}
}
provider "aws" {
region = "eu-central-1"
}
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"
}
"org/${var.circleci_org_id}/project/${var.circleci_project_id}/user/*"
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/config.yml
version: 2.1
orbs:
aws-cli: circleci/[email protected]
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 CloudTrailuser
필드로 표시됩니다.CIRCLE_OIDC_TOKEN
-> OIDC 토큰입니다. 작업이 컨텍스트를 사용하는 경우에만 CircleCI에 의해 추가됩니다. 그래서 워크플로에 example-context
를 추가했습니다. 이 컨텍스트는 비어 있을 수도 있습니다. duration-seconds
- 토큰이 유효한 시간작업에서 SSH를 사용하여 내부 내용
CIRCLE_OIDC_TOKEN
을 확인하고 여기에서 디코딩할 수 있습니다. jwt.iocircleci@a094c7852509:~$ echo $CIRCLE_OIDC_TOKEN
eyJraWQiOiJhSzlqNmRZQm8zS0R3NGdmV3k4eGRNTFU1UThPeWNzcW44S.......
선적 서류 비치
첫 글이라 피드백 환영합니다 :)
Reference
이 문제에 관하여(CircleCI를 사용하여 AWS에 배포 - OpenID Connect), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thevops/deploy-on-aws-with-circleci-openid-connect-4b0g텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)