C++ is a highly versatile language for developing console applications, batch processing, and performance-critical applications. While it has traditionally been less explored for building RESTful APIs, modern libraries like Boost, Beast, Crow, and Pistache make this possible. In this guide, we will demonstrate how to create a RESTful API using C++ with Crow framework.

In this blog post, you will explore how to create a RESTful API for a Todo List in C++; using Crow (C++ framework), containerize using Docker and create a Database using SQLite. You will also set up an automated CICD pipeline and deploy it to the Azure Container Registry (ACR) using GitHub Actions. You will also have test cases integrated from the CICD pipeline.

SQLite refers to the lightweight, self-contained relational database engine that your C++ application will likely use for data storage or retrieval.

Get Started

To follow along, ensure you have the following:

  • C++ Development Tools: A modern C++ compiler (e.g GCC)
  • SQLite: is a lightweight, self contained relational database engine which will interact with your C++ application for data storage.
  • Docker : Docker installed and running on your machine
  • GitHub Account: The code will reside in GitHub and will use GitHub Actions for running Continous Integration / Deployment (CICD)
  • Azure Account: You must have the necessary permissions to create or manage Azure resources within an existing Azure Subscription.

Step 1: Setting Up the RESTful API

You will be using Crow for building the Todo List API and sqlitefor data persistence. Crow is a C++ framework for creating HTTP or WebSocket web services. Create a file main.cpp In the root project, copy and paste the code below. main.cpp contains the logic for the Todo List API which includes the CRUD operations.

https://medium.com/media/b8e27a7f7e98cb4e66abd807ba68d947/href

Step 2: Dockerize the Application

a. Create the Dockerfile in the root project which will be used to containerize the API. Create a file with Dockerfile and copy and paste the code below

https://medium.com/media/3ea0a859989430e27db72463a10a8e1d/href

b. Create a .dockerignore file and add this code snippet. This will speed up the build process and reduce the image size.

https://medium.com/media/467eb89857ae16d8cf12ee30c56681df/href

Step 3: Build the Docker Image locally

You will build the docker image locally to see if it works perfectly and then automate this process using GitHub Actions.

a. command to build the docker image

docker build . -t todo_cpp_project:v0.0.1

b. command to run the docker image

docker run todo_cpp_project:v0.0.1

Step 4: Test the Docker Image locally

You will be testing the application using POSTMAN with the following endpoints.

  • GET Endpoint uses the resource /todos with the method GET to retrieve all the todo’s.
  • POST Endpoint uses the resource /todos with the method POST.
  • DELETE Endpoint uses the resource /todos/ with the method DELETE to delete todo.
  • PATCH Endpoint uses the resource /todos/ with the method PATCH.
  • Health Endpoint: uses the resource /health with the GET method
  • GET Endpoint for a Single Todo: uses the resource /todo/ with the method GET to get a single todo.

Health endpoint: The health endpoint checks if the app is up and running.

POST endpoint: The POST endpoint creates a todo list in the Database.

1*IKs6rhLL4GgNIU1F8Z07oQ

PUT endpoint: The PUTendpoint updates the todo list by supplying the ID.

GET endpoint: The GETendpoint retrieves the todo list.

1*u2Q35KO S7nkLA7EmaXj7w

DELETE endpoint: The DELETE endpoint deletes the todo list by supplying the ID.

1*YuDSIaHzztF3tO23ZlhJuw

Follow this Step to Deploy Docker Image to Azure Container Registry (ACR) using GitHub Actions

Step 1: Authenticate with Azure using OIDC.

Using OIDC (OpenID Connect) allows secure, short-lived and GitHub managed identities to access Azure resources without storing secrets in GitHub. OIDC uses federated tokens, which mean that Azure issues a token only when it is needed and only to a trusted identify providers (GitHub or GitLab). By using OIDC, this reduces risk of credentials getting leaks since OIDC will generate short lived credentials (temporally).

a. Login to the azure account using the appropriate Azure subscription

# Login to your azure account and select the subscription
az login

b. Set the active subscription for your Azure CLI session

Replace with your active subscription. The command below will set active subscription for your Azure CLI.

az account set --subscription 

c. Create a Federated Identity and Role Assignment.

#!/bin/bash

set -e # Exit on any error

# Variables
ACR_NAME="todocpp"
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
RESOURCE_GROUP="todo-cpp-project"
AZURE_TENANT_ID=$(az account show --query tenantId -o tsv)
AZURE_AD_APP_NAME="github-acr-oidc"
GITHUB_REPO="ExitoLab/todo_cpp_restful_docker_github_actions_azure"
LOCATION="eastus"

echo "Starting Azure setup for GitHub OIDC..."
echo "Subscription: $SUBSCRIPTION_ID"
echo "Tenant: $AZURE_TENANT_ID"
echo "GitHub Repo: $GITHUB_REPO"

# Create Resource group if it does not exist
echo "Creating resource group..."
az group create --name $RESOURCE_GROUP --location $LOCATION

# Create ACR
echo "Creating Azure Container Registry..."
az acr create --name $ACR_NAME
--resource-group $RESOURCE_GROUP
--sku Basic
--location $LOCATION
--admin-enabled true

# Create app registration
echo "Creating Azure AD app registration..."
az ad app create --display-name "$AZURE_AD_APP_NAME"

# Get clientId
APP_ID=$(az ad app list --display-name "$AZURE_AD_APP_NAME" --query "[0].appId" -o tsv)

if [ -z "$APP_ID" ]; then
echo "Error: Failed to create or retrieve app registration"
exit 1
fi

echo "App ID: $APP_ID"

# Create service principal from the app ID (skip if already exists)
echo "Creating service principal..."
if ! az ad sp show --id $APP_ID &>/dev/null; then
az ad sp create --id $APP_ID
echo "Service principal created."
else
echo "Service principal already exists, skipping creation."
fi

# Create federated credentials for different scenarios
echo "Creating federated credentials..."

# Main branch
az ad app federated-credential create --id $APP_ID --parameters '{
"name": "github-oidc-main",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:'"$GITHUB_REPO"':ref:refs/heads/main",
"description": "OIDC GitHub Main Branch",
"audiences": ["api://AzureADTokenExchange"]
}'

# Pull requests
az ad app federated-credential create --id $APP_ID --parameters '{
"name": "github-oidc-pr",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:'"$GITHUB_REPO"':pull_request",
"description": "OIDC GitHub Pull Requests",
"audiences": ["api://AzureADTokenExchange"]
}'

# Get ACR resource ID
ACR_ID=$(az acr show --name $ACR_NAME --query id -o tsv)

# Assign ACR roles
echo "Assigning ACR permissions..."
az role assignment create --assignee $APP_ID
--role "AcrPush"
--scope $ACR_ID

az role assignment create --assignee $APP_ID
--role "AcrPull"
--scope $ACR_ID

# Optional: Add Contributor role to resource group if needed for other operations
# az role assignment create --assignee $APP_ID
# --role "Contributor"
# --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP"

# Get ACR login server
ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --query loginServer -o tsv)

echo ""
echo "=== Setup Complete! ==="
echo ""
echo "Add these secrets to your GitHub repository:"
echo "AZURE_CLIENT_ID: $APP_ID"
echo "AZURE_TENANT_ID: $AZURE_TENANT_ID"
echo "AZURE_SUBSCRIPTION_ID: $SUBSCRIPTION_ID"
echo "ACR_LOGIN_SERVER: $ACR_LOGIN_SERVER"
echo ""
echo "Your GitHub Actions workflow can now authenticate with Azure using OIDC!"
echo "ACR Name: $ACR_NAME"
echo "Resource Group: $RESOURCE_GROUP"

d. The following permission will be created below

| CapabilityPermission    | Access |
|-------------------------|--------|
| Pull images | ✅ Yes |
| Push images | ✅ Yes |
| List repositories/tags | ✅ Yes |
| Delete images/tags | ✅ Yes |
| Read/write access | ✅ Yes |

Step 2: Create GitHub Actions and use the OIDC

Once you run the script above it will generate the following

echo "AZURE_CLIENT_ID: $APP_ID"
echo "AZURE_TENANT_ID: $AZURE_TENANT_ID"
echo "AZURE_SUBSCRIPTION_ID: $SUBSCRIPTION_ID"

Create a secrets in GitHub similar with screenshot below

1*cijV esUauvT9tbCkrjdug

Conclusion

This article walks you through setting up a C++ application, containerizing it with Docker, automating the CI/CD pipeline using GitHub Actions, and finally pushing the container image to Azure Container Registry (ACR). It explained the basic workflow for building and deploying a C++ application to ACR.

You also learned how to securely run workflows on GitHub Actions using OIDC (OpenID Connect) to authenticate with your Azure account.

Check out the completed code on GitHub

stat?event=post

Share.
Leave A Reply