OIDC 인증을 통한 CircleaCI-AWS 제휴 Tips

2022년 3월 26일, 기다리던 CircleaCI OIDC 지원 발표.
https://circleci.com/docs/ja/2.0/openid-connect-tokens/
좋아, 내가 블로그를 쓰려고 하자마자 클라미수 씨가 먼저 투고했어. 그래서 나는 내가 실제로 시도한 곳을 Tips로 기록했어.
https://dev.classmethod.jp/articles/circleci-supported-oidc-so-i-tried-linking-it-with-aws/

Terraform 설치


OIDC Provider


먼저 OIDC Provider 정의부터 시작합니다.
oidc_providers.tf
resource "aws_iam_openid_connect_provider" "circleci" {
  url             = "https://oidc.circleci.com/org/${local.circleci_org_id}"
  client_id_list  = [local.circleci_org_id]
  thumbprint_list = [
    "9e99a48a9960b14926bb7f3b02e22da2b0ab7280",
  ]
}

locals {
  circleci_org_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
aws_iam_openid_connect_provider 자원에 정의됩니다.
URL 및 Client ID에는 CircleaCI의 Org ID가 필요합니다.
CircleaCI의 Organization Settings→Context로 CONtext를 만들면 Organization ID가 표시됩니다.

CircleaCI 공급자의 및 인쇄는 9e99a48a9960b14926bb7f3b02e22da2b0ab7280입니다.
aws_iam_openid_connect_provider의thumbprintlist의 계산 방법도 스스로 계산할 수 있다.

IAM Role


IAM Role은 기본적으로 GiitHub 창고별로 제작되었습니다.
oidc_terraform.tf
resource "aws_iam_role" "circleci" {
  name               = "circleci"
  description        = "circleci"
  assume_role_policy = data.aws_iam_policy_document.assume_circleci.json
}

data "aws_iam_policy_document" "assume_circleci" {
  statement {
    actions = [
      "sts:AssumeRoleWithWebIdentity",
    ]

    principals {
      type        = "Federated"
      identifiers = [aws_iam_openid_connect_provider.circleci.arn]
    }
}

# terraform planできるよう、ReadOnlyAccessを付与
resource "aws_iam_role_policy_attachment" "circleci" {
  role       = aws_iam_role.circleci.name
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

창고 제한


위의 정의에서 Org은 동일하며, IAM Role ARN을 알고 있으면 AWS 인증을 다른 창고에서 사용할 수 있습니다.
무서워서 잘 제한할 거예요.aws_iam_policy_document 데이터 원본에 제한을 추가합니다.
oidc_terraform.tf
data "aws_iam_policy_document" "assume_circleci" {
  statement {
    actions = [
      "sts:AssumeRoleWithWebIdentity",
    ]

    principals {
      type        = "Federated"
      identifiers = [aws_iam_openid_connect_provider.circleci.arn]
    }

    condition {
      test     = "StringLike"
      variable = "oidc.circleci.com/org/${local.circleci_org_id}:sub"
      values   = ["org/${local.circleci_org_id}/project/${local.circleci_oidc_project_id}/user/*"]
    }
  }
}

locals {
  circleci_org_id     = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  circleci_project_id = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
}
condition에는 규제가 추가됐다.
지정할 수 있는 Claims는 Format of the OpenID Connect ID token에 기재되어 있습니다.
다만, 각 창고에 할당된 항목 ID를 포함하는sub을 사용합니다.나는 oidc.circleci.com/project-id 사용할 수 없다고 생각하지만, 안 된다.AWS 웹 사이트 ID 연합에서 사용할 수 있는 키에 적힌 키만 사용할 수 있습니다.
프로젝트 ID를 지정하여 특정 Circleci 프로젝트(GiitHub 저장소)에 대한 액세스를 제한할 수 있습니다.
기릿허브 액션스처럼 분기 단위로 규제가 이뤄지면 개발 환경만 디자인이 가능한 IAM Role과 공식 환경에 대한 디자인이 허용된 IAM Role를 분리할 수 있어 편리하고, 좀 더 세밀한 설정이 가능했으면 좋겠다.
프로젝트 ID는 Project Settings→Overview에 있습니다.

단계 간에 액세스 키 전송


두루마리 통의 한쪽을 사용하면 다음과 같다.yml을 생성합니다.
version: 2.1

orbs:
  # See https://circleci.com/developer/ja/orbs/orb/circleci/aws-cli
  aws-cli: circleci/[email protected]

jobs:
  aws:
    machine:
      image: ubuntu-2004:current
    steps:
      - checkout
      - aws-cli/install
      - run: |
          aws_sts_credentials=$(aws sts assume-role-with-web-identity \
            --role-arn ${AWS_ROLE_ARN} \
            --web-identity-token ${CIRCLE_OIDC_TOKEN} \
            --role-session-name "circleci-oidc" \
            --duration-seconds 900 \
            --query "Credentials" \
            --output "json")
          echo export AWS_ACCESS_KEY_ID="$(echo $aws_sts_credentials | jq -r '.AccessKeyId')" >> $BASH_ENV
          echo export AWS_SECRET_ACCESS_KEY="$(echo $aws_sts_credentials | jq -r '.SecretAccessKey')" >> $BASH_ENV
          echo export AWS_SESSION_TOKEN="$(echo $aws_sts_credentials | jq -r '.SessionToken')" >> $BASH_ENV
          source $BASH_ENV
      - run: aws sts get-caller-identity

workflows:
  awscli:
    jobs:
      - aws:
          context:
            - oidc
프로젝트의 Environment에 다음과 같은 환경 변수를 미리 추가합니다.
  • AWS_ROLE_ARN: 방금 만든 IAM Role의 ARN
  • AWS_DEFAULT_REGION: AWS의 영역
  • aws sts assume-role-with-web-identity에서 만든 액세스 키는 $BASH_ENV로 리디렉션을 통해 다른 단계에서 사용할 수 있습니다.
    환경 변수 사용

    좋은 웹페이지 즐겨찾기