Platform Engineering on Kubernetes with Terraform, Argo, and FastAPI - Part 2
With the groundwork established in PART 1, Part 2 dives deeper into the implementation and integration of the key components that will power our platform’s capabilities: Argo Events for event-driven automation, Argo Workflows for CI/CD pipelines, and FastAPI as the frontend API layer.
Table of Contents
Event-driven Automation
To add event-driven automation capabilities within our platform, we will configure Argo Events to integrate with an event source and trigger automated Argo workflows. Our aim is to trigger a Workflow upon receiving an HTTP POST request from FastAPI, such as when a developer initiates a request to provision a new environment or deploy an application. To achieve this, we need to create the following resources in Kubernetes.
EventBus
The EventBus resource acts as the transport layer within Argo Events, facilitating the communication between EventSources and Sensors. It serves as a central hub where EventSources publish events, and Sensors subscribe to those events to execute triggers and automated workflows. Argo Events supports three implementations of the EventBus: NATS, Jetstream, and Kafka. In our case, we are using the NATS implementation, which provides a lightweight and efficient messaging system for event distribution.
In this configuration:
- We define an EventBus resource named eventbus-nats in the argo-events namespace.
- The spec.nats.native section specifies that we are using the NATS implementation of the EventBus.
- The spec.nats.replicas field is set to 3
- The spec.nats.auth field is set to token, enabling token-based authentication for secure communication between EventSources, Sensors, and the EventBus.
To create the EventBus resource, run:
By creating an EventBus, we have established a reliable and secure messaging system to facilitate the flow of events within our platform. EventSources, such as the Webhook we are going to create in the next section, will publish events to the EventBus. Sensors, which we will configure later, will subscribe to specific events and trigger the corresponding Argo Workflows.
EventSource
The EventSource resource specifies the configurations required to consume events from external sources, such as webhooks, and transform them into CloudEvents. In our case, we are configuring a Webhook EventSource to listen for incoming HTTP requests on specific endpoints. This will allow us to trigger automated workflows based on events generated by developers interacting with FastAPI.
In this configuration:
- The EventSource is named webhook and resides in the argo-events namespace.
- It is associated with the eventbus-nats eventbus.
- The Webhook event source will listen on port 12000.
- The webhook section defines the specific endpoints that will trigger events:
- /storage: This endpoint will trigger an event when an HTTP POST request is received, to provision Azure storage resources such as Blob storage accounts and File shares
- /compute: This endpoint will trigger an event when an HTTP POST request is received, to provision Azure compute resources such as virtual machines, Kubernetes clusters.
- /database: This endpoint will trigger an event when an HTTP POST request is received, to provision Azure database resources such as SQL databases, NoSQL databases, or caches.
By defining these endpoints, we have mapped specific API calls from FastAPI to corresponding events within Argo Events. These events will then be processed and used to trigger automated workflows, such as provisioning infrastructure, deploying applications, or configuring application settings, using Argo Workflows. This configuration seamlessly integrates our platform API with Argo Events, enabling event-driven automation.
To create the EventSource resource, run:
Sensor
The Sensor defines a set of event dependencies (inputs) and triggers (outputs). It listens to events on the eventbus and acts as an event dependency manager to resolve and execute the triggers. A dependency is an event the sensor is waiting to happen. Based on the platform capabilities we described in PART 1, we are going to create the following Sensor resources in Argo Events.
-
Compute Provisioning Sensor
The compute-provision-sensor listens for events from the /compute webhook endpoint and triggers an Argo Workflow named compute-provision-workflow. The workflow executes a series of steps to provision the requested resources using Terraform.
The parameters section defines how the compute-provision-workflow receives and maps input data from the webhook event triggered by the compute-provision-sensor. These parameters allow the workflow to dynamically configure itself based on the request payload received from the webhook. Additionally, they map the values from the webhook payload to the input variables that Terraform expects for provisioning the requested resources. For example, the parameter:
maps the value from the region field in the webhook payload’s body to the first input parameter that Terraform expects for the region variable. This allows Terraform to provision the resources in the specified region based on the value provided by the developer through the webhook request.
In addition to the Compute Provisioning Sensor, we will create additional sensors as follows;
Storage Provisioning Sensor: This sensor listens for events from the /storage webhook endpoint and triggers an Argo Workflow named storage-provision-workflow. The workflow executes a series of steps to provision the requested storage resources using Terraform.
Database Provisioning Sensor: This Sensor listens for events from the /database webhook endpoint and triggers an Argo Workflow named database-provision-workflow. The workflow executes steps to provision the requested database resources using the database_config payload from the event.
To create all the sensors described above, run:
Workflow Orchestration
To add CI/CD and Workflow Orchestration capabilities within our platform, we will configure Argo Workflows to orchestrate the end-to-end processes triggered by developer requests received via the Argo Events sensors. For example, when a developer calls the /compute endpoint in FastAPI, to provision a new compute resource, Argo Workflows will execute a series of steps required to fulfill the request using Terraform.
-
Workflow Images
Argo Workflows provides different types of templates to define the steps within a workflow. Two commonly used templates are the script template and the container template. Both execute containers based on specified Docker images. This means we need a Docker image that includes all the necessary packages, tools, and dependencies required to execute our workflows. This custom image should include Terraform for provisioning cloud infrastructure, the Azure CLI for interacting with Azure services, the Argo CLI for managing Argo Workflows, Ansible for configuration management, and any other utilities or libraries our workflows might require.
You can use this custom image directly or adapt for your use case. Build the custom image and publish it to your container registry
-
Workflow Templates
The compute-provision-workflow template is triggered by the compute-provision-sensor in response to events received from the /compute webhook endpoint. Upon receiving the event from the sensor, the workflow executes a series of steps to provision the requested resources using Terraform.
The workflow follows these general stages:
- The workflow first validates the input parameters received from the webhook event, ensuring that all required information is provided, such as the cloud provider, resource type, region etc.
- Based on the requested resource type and cloud provider, the workflow retrieves the appropriate Terraform configuration files or modules from a centralized repository.
- The workflow initializes the Terraform working directory by downloading the required provider plugins and setting up the necessary backend configuration.
- Terraform performs a dry-run plan operation, generating an execution plan that outlines the changes required to provision the requested resources.
- Depending on the configuration, the workflow may include an approval step where manual intervention or approval is required before proceeding with the actual resource provisioning.
- If the plan is approved (or if approval is not required), the workflow executes the Terraform apply command, provisioning the requested resources in the specified cloud environment.
- Upon successful provisioning, the workflow generates output artifacts containing information about the provisioned resources, such as IP addresses, resource IDs, or connection details. Additionally, it can send notifications to the requesting developer or relevant stakeholders, informing them of the provisioning completion.
- Finally, the workflow cleans up any temporary files or directories used during the provisioning process.
-
Artifact Repositories
Some of the workflows executed on our Platform will use input and output artifacts. To enable this, we will configure an Azure Storage Account as our artifacts store.
-
Workflow Volumes
We leverage Kubernetes Secrets to securely store and manage sensitive information, such as credentials for infrastructure provisioners (e.g., cloud provider credentials), database server passwords and other confidential data. The secrets are retrieved from Azure Key Vault using the External Secrets solution we created in PART 1. To inject these Secrets into our workflow, we mount them as Kubernetes Volumes within our workflow definition like this:
To create all the workflow templates described above, run:
Summary
In this second part of the series, we enhanced our internal developer platform by integrating Argo Events for event-driven automation and Argo Workflows for workflow orchestration. This enables developers to trigger automated provisioning of infrastructure and applications through a seamless API experience.
The key implementations are:
- EventBus: A NATS-based central messaging hub for efficient event distribution between EventSources and Sensors.
- EventSource: A Webhook EventSource configured to listen for HTTP POST requests from FastAPI.
- Sensors:
- Compute Provisioning Sensor listens for /compute events to trigger compute-provision-workflow for provisioning compute resources like VMs and Kubernetes clusters using Terraform.
- Storage Provisioning Sensor listens for /storage events to trigger storage-provision-workflow for provisioning storage resources like Blob Storage and File Shares.
- Database Provisioning Sensor listens for /database events to trigger database-provision-workflow for provisioning database resources like SQL and NoSQL databases.
- Workflow Templates: Defining stages for provisioning requested resources using Terraform based on dynamic parameters
- Artifact Repositories and Volumes: An Azure Storage Account configured as an artifact store, and Kubernetes Secrets used to securely manage sensitive data like cloud provider credentials.
This integration enables event-driven automation, where developer requests received via the FastAPI frontend trigger corresponding Argo Workflows to provision and manage infrastructure and applications on Kubernetes using Terraform. Our platform now handles the intricate details of provisioning, deployment, and management in a streamlined manner. In the upcoming part of this series, we will dive deeper into the implementation of the FastAPI frontend API layer, providing developers with an intuitive interface to interact with the platform’s capabilities.