In this tutorial we will see how to add GitHub actions IP dynamically to AWS security group. Whenever a workflow runs, Github actions IP will be added to the security group and removed when the jobs are done.
If you use AWS security group to protect your infrastructure from any external access and you also use Github Action for CI/CD, you might need to allow Github Actions IP in AWS security group so that the workflow can execute the tasks in your instance. However, finding Github actions IP ranges and adding them to security groups is not a dynamic solution. Moreover, those IPs change very often.
So, to solve this issue dynamically, we will:
- Grab github action IP from running job
- Add it to the security groups via aws-cli
- SSH and deploy the code to the instance
- Remove the action IP from security group for cleanup
- Profit!
Prerequisite:
First, create an IAM user and make sure to tick “Programmatic access”
Attach the following inline policy to the user. This policy will allow the user to modify AWS security group. At line 11, make sure to replace your-account-id & your-security-group-id
{ "Version": "2012-10-17", "Statement": [ { "Sid": "UpdateIngress", "Effect": "Allow", "Action": [ "ec2:RevokeSecurityGroupIngress", "ec2:AuthorizeSecurityGroupIngress" ], "Resource": "arn:aws:ec2:your-region:your-account-id:security-group/your-security-group-id" }, { "Sid": "DescribeGroups", "Effect": "Allow", "Action": "ec2:DescribeSecurityGroups", "Resource": "*" } ] }
Finally note the aws secret id and access key of the user and add them to your project’s secret.
Create the workflow
Now, in your project, create a workflow. Lets name it prod.yaml and paste the following codeblocks:
name: Deploy to prod # on: # workflow_dispatch: on: push: branches: [ master ] jobs: deploy: runs-on: ubuntu-18.04 steps: - name: Get Github action IP id: ip uses: haythem/public-ip@v1.2 - name: Setting environment variables.. run: | echo "AWS_DEFAULT_REGION=ap-southeast-1" >> $GITHUB_ENV echo "AWS_SG_NAME=default" >> $GITHUB_ENV - name: Add Github Actions IP to Security group run: | aws ec2 authorize-security-group-ingress --group-name ${{ env.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32 env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ env.AWS_DEFAULT_REGION }} - name: Deploy to prod server uses: appleboy/ssh-action@master with: host: 11.22.33.44 username: ubuntu key: ${{ secrets.SSH_KEY }} script: | cd /var/www/html/my-awesome-project git stash git pull origin master - name: Remove Github Actions IP from security group run: | aws ec2 revoke-security-group-ingress --group-name ${{ env.AWS_SG_NAME }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32 env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ env.AWS_DEFAULT_REGION }} if: always()
This workflow will run only when there is a push in the master branch. If you want to run this workflow manually, uncomment line 3-4 and comment line 5-7
At line 12-14, we grab the GitHub action IP. From 16-19, two environment variables are set globally. Put your region and security group at line 18-19. I am using default security group and ap-southeast-1 as the region.
From 21-27, we are adding the GitHub action IP to AWS security group.
From line 29-38, we login to the instance and pull the code. Please make sure that the host IP address is correct and SSH_KEY (for accessing the server) in the project’s secret is valid.
After successfully deploying the code, at line 40-46, we remove the Github actions IP from the security group.
Hi, i found your solution very usefull and straigthforward, thanks for sharing it!, but whats means or what it’s AWS_ACCESS_KEY_ID in the secrets?
Hey, thanks. When you give a user programmatic access, the user will have access key and secret which will be used to call AWS resources via api. You can see this solution on how to obtain the key and secret
If the security group is not in the default VPC you’ll need to use the –group-id flag and sg-id instead of name. Something to be aware of that tripped me up at first. Thanks for info!
Hey, thanks for your input.
a couple of questions about the –group-id placement. Would it be at lines 19,23,42
replacing SG_NAME with SG_ID
and within 23 and 42 replacing –group-name with –group-id?
can you please provide an example for setting the –group-id flag and sg-id because am keep receiving this error
Unknown options: -–group-id, –sg-id
‘–group-id’ is an option in the aws ec2 cli. it is prefixed with two dashes. do not copy it from this web page, type it yourself. html and css often replace two dashes with one long dash, which is not the same thing.
‘sg-id’ means enter the ‘Security group ID’ for your security group.
you can find yours at:
https://us-east-1.console.aws.amazon.com/ec2/v2/home?region=us-east-1#SecurityGroups:
NOTE: change ‘us-east-1’ to your region in BOTH places in the above url.
works perfect thanks for this
glad it helped 🙂
a couple of questions about the –group-id placement. Would it be at lines 19,23,42
replacing SG_NAME with SG_ID
and within 23 and 42 replacing –group-name with –group-id?
Great article, thanks!