Github actions에서 OIDC를 이용한 AWS 배포관리

7/27/2022

Access key, Secret 방식의 문제점

Github actions workflow를 활용해서 테스트/배포 등을 관리하는 경우 필수적으로 클라우드 서비스(AWS, GCP, Azure같은) 접근권한이 필요하다.

이 때 일반적으로 클라우드 provider가 제공하는 패스워드나 토큰을 이용하는데 보통 github secret에 직접 값을 저장하고 workflow에서 저장된 값을 이용해 배포 커맨드를 실행하는 형태로 활용한다.

그런데 일단 배포에 필요한 권한 이상으로 설정된 IAM User의 credential을 저장소에 복사해서 담아놓는것의 찝찝함은 둘째치고 일단 값을 복사해서 저장소에 넣어놓는 과정 자체가 귀찮다. 거기다 credential 정보가 털리면 직접 revoke하기 전까진 매우 위험한 상황에 놓이게 된다.(Admin 권한이면 재앙)

OpenID Connect(OIDC)가 뭐임?

OpenID Connect란 OAuth 2.0 framework를 기반으로 만들어진 identity layer이다. Third party application이 사용자의 identity를 검증하고 프로필 정보를 얻는데 활용한다.

자세한건 여기

어쨌든 github에서 cloud provider에게 접근 권한을 요청하면 짧은 기간동안만 유효한 토큰을 발급해주고 해당 토큰을 이용해 배포에 필요한 자원에 접근하는 방식이다.

job이 끝난 이후엔 자동으로 토큰이 만료되기 때문에 access key를 직접 저장소에 보관하는 방식보다 훨씬 안전하다.

설정은 어떻게?

Provider 설정

AWS를 기준으로 여기에 자세히 잘 설명되어 있다.

먼저 Identity provider를 설정해주어야 한다.

  1. 우선 IAM - Identity providers 메뉴에서 Add provider
  2. provider URL, Audience에 각각 https://token.actions.githubusercontent.com, sts.amazonaws.com 입력

다음으로 아래와 같이 Role을 설정해준다.

  1. IAM > Roles 메뉴에서 Create role 버튼 클릭
  2. Trusted entity typeWeb identity를 선택하고 아래의 identity provider, Audience에 위에서 등록한 값을 선택하고 Next
  3. 다음 단계에서 배포에 필요한 권한을 추가(s3, cloudfront 등)

이제 aws에서의 설정은 끝이났고 github action에 설정을 추가해주어야 한다.

Github Actions 설정

아래의 두가지 설정을 workflow yaml에 추가해주어야 한다.

  1. token에 대한 permission 추가
  2. aws-actions/configure-aws-credentials 액션 관련 설정

대충 아래와 같은 형태로 yaml파일을 설정해주면 된다

# Sample workflow to access AWS resources when workflow is tied to branch
# The workflow Creates static website using aws s3
name: AWS example workflow
on:
push
env:
BUCKET_NAME : "<example-bucket-name>"
AWS_REGION : "<example-aws-region>"
# permission can be added at job level or workflow level
permissions:
id-token: write
contents: read # This is required for actions/checkout
jobs:
S3PackageUpload:
runs-on: ubuntu-latest
steps:
- name: Git clone the repository
uses: actions/checkout@v3
- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::1234567890:role/example-role
role-session-name: samplerolesession
aws-region: ${{ env.AWS_REGION }}
# Upload a file to AWS s3
- name: Copy index.html to s3
run: |
aws s3 cp ./index.html s3://${{ env.BUCKET_NAME }}/

이제 저장소에 access key와 secret을 저장해두지 않고도 프로젝트를 자동으로 배포할 수 있게 되었다.


Powered by Gatsby