In Part 1 of this series, we built a PowerShell script that automates the process of pulling a public Docker image from Docker Hub and pushing it to your Azure Container Registry (ACR). In this second part, we'll focus on integrating that script into a CI/CD pipeline using GitHub Actions. This logic will ensure that our image management process is fully automated and runs on a scheduled basis.
With GitHub Actions, you can schedule the execution of your script, monitor its output, and ensure that your ACR is always updated with the latest image—without any manual intervention. Let’s walk through how to configure your GitHub Actions workflow.
⚙️ Setting Up the GitHub Actions Workflow
First, ensure that your PowerShell script (scripts\Sync-AzContainerRegistry.ps1
) from Part 1 is checked into your repository. Next, create a GitHub Actions workflow file (for example, .github/workflows/update-acr-image.yml
) with the following content:
name: CloudFlared Image Sync
on:
schedule:
- cron: '0 0,12 * * *' # Runs at 00:00 UTC and 12:00 UTC every day
push:
branches:
- main
permissions: # for open-id federated credentials
id-token: write
contents: read
jobs:
push_image:
runs-on: ubuntu-latest
env:
ACR_NAME: "---YOUR_ACR_NAME---"
RESOURCE_GROUP_NAME: "---YOUR_RESOURCE_GROUP_NAME---"
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
uses: azure/login@v2
with:
enable-AzPSSession: true
client-id: "CLIENT_ID"
tenant-id: "TENANT_ID"
subscription-id: "SUBSCRIPTION_ID_WHERE_ACR_IS"
# This is federated credentials
- name: Push Docker Image to Target Registry
uses: azure/powershell@v2
with:
azPSVersion: "latest"
inlineScript: |
.\scripts\Sync-AzContainerImages.ps1 -acrName "${{ env.ACR_NAME }}" -resourceGroupName "${{ env.RESOURCE_GROUP_NAME }}"
Explaining the Workflow
Triggering the Workflow:
Theon
section specifies that the workflow will run on a schedule defined by the cron expression0 0,12 * * *
, meaning it will execute at 00:00 UTC and 12:00 UTC every day. Additionally, the workflow will trigger on every push to themain
branch.Job Configuration:
The job runs on anubuntu-latest
virtual machine provided by GitHub Actions, ensuring a consistent and up-to-date environment. You might need to adjust the runner based on your requirements if Azure Container registry is locked down the network.Environment Variables:
The environment variablesACR_NAME
andRESOURCE_GROUP_NAME
are set for use in the script. These variables allow you to easily configure the target Azure Container Registry and resource group without modifying the script.Checkout Step:
Theactions/checkout@v3
step checks out the latest version of your repository, ensuring that all necessary files—including the PowerShell script—are available on the runner.OIDC Login to Azure:
Theazure/login@v2
action is used for OIDC-based authentication to Azure Public Cloud. This step leverages federated credentials, allowing secure, least-privilege authentication using a Service Principal. The login action also enables an Az PowerShell session (enable-AzPSSession: true
).Running the Script:
Theazure/powershell@v2
action sets up the latest Azure PowerShell environment and runs the inline script. This step executes your PowerShell script (scripts\Sync-AzContainerRegistry.ps1
) with the provided parameters (such as ACR name and resource group) to sync images from Docker Hub to your ACR. The Service Principal credentials are managed securely via GitHub Secrets, ensuring that authentication happens securely and with minimal privileges.
These steps combined create a decent CI/CD pipeline that automates your image management process, ensuring that your Azure Container Registry is continuously updated with the latest Docker image.
Benefits of Integrating with CI/CD
- No manual intervention is needed to update your ACR; the process runs automatically on a schedule when you're sleeping or enjoying your weekend 🎉.
- Your container images are always up to date, reducing discrepancies between Docker Hub and your private registry and plus, you can avoid Docker Hub rate limits.
- By automating the process, you reduce the risk of running outdated or vulnerable container images in your environment. That being said, you should still monitor your images for vulnerabilities and update them as needed.
- Additionally, you can extend this pipeline to include other tasks, such as running tests, deploying your container and scanning for vulnerabilities.
Conclusion
In this part of our series, we've integrated our PowerShell script into a GitHub Actions pipeline, automating the process of synchronizing Docker Hub images with your Azure Container Registry. This setup not only overcomes Docker Hub’s rate limits but also ensures that your deployment environment is always running the most up-to-date, secure container images.
Have you tried automating your image management process with GitHub Actions? Share your experience reaching out to me.