Giới thiệu
Dự án của mình hiện tại sử dụng GitHub để quản lý source code và môi trường AWS để vận hành hạ tầng.
Khi sử dụng GitHub thì dự án mình cũng có sử dụng Github Action cho một số mục đích như một phần trong chu trình CICD
- Scan Vulnerabilities Docker image
- Check golang lint
- Build Docker image, push to ECR
- Deploy Lambda
- Deploy Bastion host
- v.v
Để liên kết giữa GitHub Action và AWS, trước đây dự án mình dùng IAM User Access Key, tuy nhiên dùng long-term credentials không được khuyến khích nên mình đã chuyển sang dùng OIDC Authentication.
Bài viết này nhằm giới thiệu về OIDC và một bài Demo nhỏ - Deploy Multi lambda sử dụng GitHub Action
OIDC là gì?
OpenID Connect (OIDC) là giao thức xác thực người dùng dựa trên OAuth 2.0.
OpenID Connect (OIDC) allows your GitHub Actions workflows to access resources in Amazon Web Services (AWS), without needing to store the AWS credentials as long-lived GitHub secrets.
Các ứng dụng của bên thứ ba xác thực người dùng thông qua OIDC và trao đổi thông tin người dùng một cách an toàn bằng cách sử dụng JWT (JSON Web Token). Nó cung cấp xác thực an toàn và linh hoạt hơn so với các phương thức xác thực khác.
Tại sao nên sử dụng OIDC?
Trước đây dự án mình sử dụng IAM User Access key và Secret key, lưu các giá trị này trong Secret của Github và sử dụng để liên kết với AWS
Setting:
Github workflow
# Ref. https://github.com/aws-actions/configure-aws-credentials
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEV }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }}
aws-region: us-east-1
Các biến này được mã hóa vì chúng được lưu dưới dạng Secret
. Nhưng có một vấn đề là những thông tin này lưu ở bên ngoài AWS dưới dạng long-term credentials, và các vấn đề về rotation hay nguy cơ rò rỉ.
Mặt khác, nếu chuyển sang phương thức xác thực OIDC, bạn sẽ sử dụng temporary credentials
gắn với IAM Role khi truy cập tài nguyên AWS từ workflow của GitHub Actions. Thông tin này là ngắn hạn nên ngay cả khi chúng bị lộ, rủi ro cũng sẽ thấp hơn.
Authentication Flow
Architecture Diagram
Diagram bên dưới thể hiện mối quan hệ khi sử dụng GitHub Actions để truy cập vào môi trường AWS thông qua OIDC Authentication.
Flow thực thi
- Chuẩn bị GitHub OIDC provider phía AWS Account
- Chuẩn bị IAM Role dùng cho Github Repo đã Trust với GitHub OIDC provider
- Chỉ định Assume Role tại workflow của GitHub Actions
1. Tạo OICD Provider
Hướng dẫn này mình sử sụng Console để thực hiện:
Tại IAM Console -> Identity providers -> Add provider
Configure provider
- Provider type:
OpenID Connect
- Provider URL:
https:// token.actions.githubusercontent.com
- Audience:
sts.amazonaws.com
2. Create IAM Role dùng để Xác thực thông qua OIDC
- Role name:
CMPGitHubActionsRole
- Permissions policies (Bài demo bên dưới mình sẽ sử dụng các policy sau)
- AmazonS3FullAccess
- AWSCloudFormationFullAccess
- AWSLambda_FullAccess
- CloudWatchLogsFullAccess
- Trust relationships (mình muốn IAM Role này trust chỉ những git repo của mình)
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::067057696393:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": [
"repo:cloudmentor-pro/*"
]
}
}
}
]
}
Bạn có thể cho phép toàn bộ repo, một vài repo hoặc trên các branh cụ thể
Case 1: Cho phép toàn bộ branch trên 1 repo cụ thể
StringLike:
token.actions.githubusercontent.com:sub:
- 'repo:<GitHub username>/<GitHub repo name>:ref:refs/heads/*'
Use-Case 2: Cho phép các branch có tiền tố cụ thể trong repo cụ thể
StringLike:
token.actions.githubusercontent.com:sub:
- 'repo:<GitHub username>/<GitHub repo name>:ref:refs/heads/prefix-*'
Use-case 3: Cho phép nhiều branch cho một repo cụ thể
ForAnyValue:StringLike:
token.actions.githubusercontent.com:sub:
- 'repo:<GitHub username>/<GitHub repo name>:ref:refs/heads/develop'
- 'repo:<GitHub username>/<GitHub repo name>:ref:refs/heads/feature'
Use-case 4: Cho phép nhiều branch cho một repo cụ thể và cũng cho phép các workflow được kích hoạt bởi pull_request
ForAnyValue:StringLike:
token.actions.githubusercontent.com:sub:
- 'repo:<GitHub username>/<GitHub repo name>:ref:refs/heads/develop'
- 'repo:<GitHub username>/<GitHub repo name>:ref:refs/heads/feature'
- 'repo:<GitHub username>/<GitHub repo name>:pull_request'
3. Setting Github Action Workflow
Để Xác thực truy cập đến AWS từ Github Action, chúng ta sẽ sử dụng Action: aws-actions/configure-aws-credentials
Ví dụ bên dưới cho workflow sử dụng GitHub Actions, Authen bằng OIDC, Login vào AWS Elastic Container Registry (ECR) và Build and push docker image lên ECR.
name: ECR Push Workflow
on:
push:
branches:
- develop
jobs:
deploy:
name: Deploy to ECR
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: YOUR_AWS_REGION
role-to-assume: YOUR_OIDC_ROLE_ARN
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: YOUR_ECR_REPOSITORY_NAME
IMAGE_TAG: latest
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
Khi chúng ta merge code vào branch develop hoặc push code lên branch develop, Action này sẽ được kích hoạt.
Demo
Để ứng dụng OIDC, mình sẽ trích xuất 1 Use-case cụ thể trong trong dự án hiện tại: Deploy multi lambda fucntion sử dụng Github Action.
- Demo này sẽ deploy những lambda fucntion nào có thay đổi source code. (Source lambda không thay đổi source code thì không deploy)
- Có 3 môi trường: develop, staging, production tương tứng với các branch develop, staging, production
- merge/push code lên branch develop sẽ Deploy lên AWS Account cho môi trường develop (staging và production cũng tương tự)
- Lambda viết bằng go, sử dụng SAM để deploy
- Github Action sẽ thực thi các SAM command
1. Chuẩn bị
- Confirm đã tạo OICD Provider (phía trên)
- Confirm đã tạo IAM Role cho GitHubAction (phía trên)
- Fork Source Code and clone
- Tạo S3 bucket: Tham khảo
BUCKET_NAME
trong Makefile (Source code) - Cập nhật Account ID của bạn trong file
_go_lambda_deploy.yml
2. Test Github Action
- Create branch develop
- Change something like this
- Push to
develop
branch
3. Confirm Action running
4. Confirm Lambda are created
Tài liệu tham khảo