-
Notifications
You must be signed in to change notification settings - Fork 0
154 lines (130 loc) · 5.03 KB
/
ci-cd.yml
File metadata and controls
154 lines (130 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
name: CI/CD Node.js → AWS Lambda + API Gateway + Terraform
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
terraform:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
TF_VAR_public_key: ${{ secrets.EC2_PUBLIC_KEY }} # GitHub secret for EC2 public key
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.15.0-alpha20251203
- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Terraform Init
working-directory: ./terraform
run: terraform init
- name: Terraform Plan
working-directory: ./terraform
run: terraform plan -out=tfplan -input=false
- name: Terraform Apply
working-directory: ./terraform
run: terraform apply -input=false tfplan
# ✅ Safely export Terraform outputs to GitHub Actions env
- name: Set Terraform outputs as env
id: tf_outputs
working-directory: ./terraform
run: |
echo "DB_HOST=$(terraform output -raw rds_host)" >> $GITHUB_ENV
echo "DB_PORT=$(terraform output -raw rds_port)" >> $GITHUB_ENV
echo "DB_NAME=${{ secrets.DB_NAME }}" >> $GITHUB_ENV
echo "DB_USER=${{ secrets.DB_USER }}" >> $GITHUB_ENV
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> $GITHUB_ENV
build-and-test:
needs: terraform
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Run tests
env:
# ✅ Use DB_HOST/DB_PORT from terraform output
DB_HOST: ${{ env.DB_HOST }}
DB_PORT: ${{ env.DB_PORT }}
DB_NAME: ${{ env.DB_NAME }}
DB_USER: ${{ env.DB_USER }}
DB_PASSWORD: ${{ env.DB_PASSWORD }}
run: npm test || echo "Skipping tests temporarily"
deploy:
needs: terraform
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Zip project
run: zip -r function.zip .
- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_REGION }}
role-session-name: github-actions-deploy
- name: Deploy Lambda with rollback
id: deploy
run: |
LAMBDA_NAME="${{ secrets.LAMBDA_FUNCTION_NAME }}"
if aws lambda get-alias --function-name $LAMBDA_NAME --name prod; then
PREV_VERSION=$(aws lambda get-alias --function-name $LAMBDA_NAME --name prod --query 'FunctionVersion' --output text)
else
CUR_VERSION=$(aws lambda publish-version --function-name $LAMBDA_NAME --query 'Version' --output text)
aws lambda create-alias --function-name $LAMBDA_NAME --name prod --function-version $CUR_VERSION
PREV_VERSION=$CUR_VERSION
fi
echo "Previous Lambda version: $PREV_VERSION"
aws lambda update-function-code --function-name $LAMBDA_NAME --zip-file fileb://function.zip
echo "Waiting for Lambda update to complete..."
while true; do
STATUS=$(aws lambda get-function --function-name $LAMBDA_NAME --query 'Configuration.LastUpdateStatus' --output text)
echo "Lambda update status: $STATUS"
if [ "$STATUS" == "Successful" ]; then
break
elif [ "$STATUS" == "Failed" ]; then
echo "Lambda update failed. Exiting."
exit 1
else
sleep 5
fi
done
NEW_VERSION=$(aws lambda publish-version --function-name $LAMBDA_NAME --query 'Version' --output text)
echo "New Lambda version: $NEW_VERSION"
aws lambda update-alias --function-name $LAMBDA_NAME --name prod --function-version $NEW_VERSION || \
aws lambda update-alias --function-name $LAMBDA_NAME --name prod --function-version $PREV_VERSION
- name: Deploy API Gateway
run: |
aws apigateway create-deployment \
--rest-api-id ${{ secrets.API_ID }} \
--stage-name ${{ secrets.STAGE_NAME }} \
--description "Deployed via GitHub Actions"