CircleCI를 사용하여 AWS에 배포 - OpenID Connect

배포 구성 중에 가장 먼저 수행하는 작업 중 하나는 CI/CD 도구에 대한 자격 증명을 만드는 것입니다.
AWS의 경우 가장 간단한 방법은 프로그래밍 방식 키로 IAM 사용자를 생성하는 것입니다. CI/CD 도구 내부의 비밀 또는 환경 변수에 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 로 배치됩니다. 기본적으로 만료 시간이 없기 때문에 장기 자격 증명이라고 합니다. 직접 회전시켜야 합니다.

더 안전한 다른 방법은 특정 시간이 지나면 자동으로 무효화되는 단기 자격 증명을 사용하는 것입니다.
이 기사에서는 *OpenID Connect 프로토콜, CircleCI를 배포 플랫폼으로, AWS를 대상으로 사용하는 예제 솔루션을 제시합니다. 프로토콜 세부 사항에 대해서는 다루지 않겠습니다.

주요 아이디어 개요



이것은 전체 프로세스가 어떻게 보이는지 보여주는 단순화된 다이어그램입니다.



AWS에서 승인하려면 2가지가 필요합니다.
  • OIDC 토큰
  • AWS IAM 역할

  • 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_idcircleci_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에서 권한을 부여하는 데 사용되는 사용자 지정 명령이 포함된 구성이 있습니다. 몇 가지 중요한 사항이 있습니다.
  • 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

  • 첫 글이라 피드백 환영합니다 :)

    좋은 웹페이지 즐겨찾기