基于EC2自动扩缩容的Node.js应用GitHub CI/CD部署方案咨询
解决方案:EC2自动扩缩容场景下的GitHub CI/CD与私有仓库访问
针对你的三个核心需求,以下是具体实现方案:
一、搭建GitHub Workflows CI/CD流水线,实现代码推送自动部署到EC2
推荐使用AWS Systems Manager (SSM) Run Command结合GitHub Actions OIDC身份验证,避免硬编码SSH密钥或凭证:
1. 前置配置
- 在AWS IAM中配置GitHub OIDC身份提供商,允许你的GitHub仓库的Actions工作流获取临时AWS凭证
- 创建IAM角色,赋予以下权限:
ssm:SendCommand:允许执行EC2实例命令s3:PutObject:允许上传构建产物到S3(若采用构建产物存储方案)- 角色信任策略限定为仅你的GitHub仓库的Actions工作流能假定该角色
2. GitHub Workflow示例(.github/workflows/deploy.yml)
name: Deploy to EC2 on: push: branches: [main] jobs: build-and-deploy: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' - name: Install dependencies and build run: | npm install npm run build - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/GitHubActionsEC2DeployRole aws-region: YOUR_AWS_REGION - name: Upload build artifacts to S3 run: aws s3 sync ./dist s3://YOUR_BUCKET_NAME/demo-website/latest - name: Deploy to EC2 instances via SSM run: | aws ssm send-command \ --document-name "AWS-RunShellScript" \ --targets "Key=tag:Name,Values=ASG-Demo-Website" \ --parameters commands=" mkdir -p /demo-website aws s3 sync s3://YOUR_BUCKET_NAME/demo-website/latest /demo-website systemctl restart demo-website.service "
二、EC2自动扩缩容时拉取最新代码
修改user-data.sh脚本,让实例启动时从S3拉取预构建的最新产物(或通过下文的PAT替代方案拉取GitHub仓库代码):
基于S3的拉取脚本(推荐,无需直接访问GitHub)
# 安装AWS CLI(若AMI未预装) apt-get update && apt-get install -y awscli # 从S3拉取最新构建产物 mkdir -p /demo-website aws s3 sync s3://YOUR_BUCKET_NAME/demo-website/latest /demo-website # 启动Node.js服务 systemctl start demo-website.service
若需直接拉取GitHub仓库代码
结合下文的Deploy Keys或GitHub App方案,将密钥获取逻辑加入user_data脚本即可。
三、不使用PAT访问私有GitHub仓库的替代方案
1. GitHub Deploy Keys
- 生成SSH密钥对:
ssh-keygen -t ed25519 -C "ec2-deploy@example.com" - 将公钥添加到GitHub仓库的「Settings > Deploy keys」,勾选「Allow write access」(若需推送权限)
- 将私钥存储到AWS Secrets Manager,在user_data中获取并配置:
# 从Secrets Manager获取私钥 aws secretsmanager get-secret-value --secret-id github-deploy-key --query SecretString --output text > /root/.ssh/id_ed25519 chmod 600 /root/.ssh/id_ed25519 # 配置Git信任GitHub主机 ssh-keyscan github.com >> /root/.ssh/known_hosts # 克隆仓库 mkdir -p /demo-website cd /demo-website git clone git@github.com:test.git .
2. GitHub App
- 创建GitHub App,赋予仓库「Contents: Read」权限,生成App私钥并存储到AWS Secrets Manager
- 在EC2实例中,使用App私钥生成临时访问令牌,用于HTTPS克隆:
# 从Secrets Manager获取App私钥和ID APP_ID=$(aws secretsmanager get-secret-value --secret-id github-app --query SecretString --output text | jq -r '.app_id') PRIVATE_KEY=$(aws secretsmanager get-secret-value --secret-id github-app --query SecretString --output text | jq -r '.private_key') # 生成JWT令牌,获取安装访问令牌(需预装jq和openssl) JWT=$(echo -n '{"iat":'$(date +%s)',"exp":'$(date -d "+10 minutes" +%s)',"iss":'$APP_ID'}' | openssl dgst -sha256 -sign <(echo "$PRIVATE_KEY") | base64 -w 0) INSTALL_TOKEN=$(curl -s -H "Authorization: Bearer $JWT" -H "Accept: application/vnd.github.v3+json" https://api.github.com/app/installations/YOUR_INSTALLATION_ID/access_tokens | jq -r '.token') # 克隆仓库 mkdir -p /demo-website cd /demo-website git clone https://x-access-token:$INSTALL_TOKEN@github.com/test.git .
3. 预构建产物存储到S3(最简化方案)
完全绕开直接访问GitHub仓库,通过CI/CD将构建好的产物上传到S3,EC2实例启动时从S3拉取,如第二部分所示。
补充:Terraform配置优化
建议将S3桶名称、IAM角色ARN等参数抽为变量,避免硬编码:
variable "aws_region" { type = string default = "us-east-1" } variable "s3_bucket_name" { type = string } resource "aws_launch_configuration" "awslc" { name_prefix = "asg-" image_id = "ami-09e647bf7a368e505" instance_type = "t2.micro" user_data = templatefile("user-data.sh", { s3_bucket_name = var.s3_bucket_name }) security_groups = [aws_security_group.web.id] lifecycle { create_before_destroy = true } }
内容的提问来源于stack exchange,提问作者SKS
相关产品推荐
相关产品推荐

