How to Whitelist Azure DevOps IP Addresses on AWS for Pipelines / Releases Hosted Agents

Jian Jye
3 min readAug 3, 2022

I thought that whitelisting Azure DevOps IP Addresses for the hosted agents to execute against my firewalled applications on AWS would be as simple as adding a range of permanent IP addresses and forget about it. Turns out that it’s much more complicated than that. Here I share a technique that I use to whitelist my Hosted Agent’s IP address on runtime, execute the job, then revoke the access from AWS, which turned out to be quite simple as well if you have the commands nailed down.

Whitelisting Azure DevOp’s IP ranges are not straight forward because:

  1. They do not have a specific section in their IP Ranges .json dump, hence we practically have to add all of the ranges within a region.
  2. The IP addresses are updated weekly. Not a fun idea for a lazy programmer.
  3. There are security risks when we whitelist such a large range of IP addresses.

Work Around

Stackoverflow

Thankfully, silent on Stackoverflow recommended this method that pointed me down to the right direction, and I was able to get it up and running successfully.

The Script

The script is pretty simple. Assuming that you already have the proper IAM set up on AWS side as well as AWS CLI set up on the Azure DevOps side, you can add a “Bash Script” job that contains the following:

# 1. Get Agent's IP
currentIp=$(curl ipinfo.io/ip)
echo $currentIp
# 2. Authorize access
aws ec2 authorize-security-group-ingress \
--region us-west-2 \
--group-id sg-xxxx \
--protocol tcp \
--port yy \
--cidr $currentIp/32
# 3. Some commands to run
<commands to be executed here>
exitCode=$?
# 4. Revoke access
aws ec2 revoke-security-group-ingress \
--region us-west-2 \
--group-id sg-xxxx \
--protocol tcp \
--port yy \
--cidr $currentIp/32
# 5. Fail the job if command failed
if [ $exitCode -ne 0 ]; then
exit 1
fi

Basically what the script does is as followed:

  1. We need to find out what’s the Hosted Agent’s IP Address, so we curl the third-party website to find out then store it into a variable called $currentIp.
  2. We ask AWS to whitelist this specific IP address $currentIp onto a security group called sg-xxxx for port yy. We also store the exit status into a variable $exitCode so that we can reuse this later. $? is a Bash specific variable for the exit code of the previous command executed.
  3. Then we execute the commands against our AWS resources as needed.
  4. And we revoke the access regardless of whether the commands are run successfully or not. While testing, you may want to comment out this step just so that you can see that the rules are indeed being added to the AWS Security Group.
  5. We added an additional step to check if our main command have failed to decide the right exit code to return. This is because if we don’t do that, even if the command have failed, if the Revoke Access step did not fail, the job would be marked as successful, which is not what we want. If you have a long chain of commands to be executed, your exitCode checks might need to be more complex.

There you go, you should now be able to access the AWS resources directly from Azure DevOps!

Was it helpful?

If you find this article helpful, do give me a little clap on Medium. 😄 It really makes my day to know that I have helped a fellow developer out there. Thanks!

--

--

Jian Jye

I write about Laravel, PHP, and web development related articles.