Deploy Azure Logic Apps with API Connections Using the Layering Method with Terraform
- Akila Induranga
- Intern - WSO2
Today, Terraform has become the go-to option for infrastructure as code (IaC) among developers for many reasons. It is an open-source solution with support from various cloud providers and uses the coder-friendly HCL syntax. Terraform is often preferred over other IaC options, such as AWS CloudFormation and Azure Resource Manager, due to its flexibility, ease of use, and platform independence.
Azure Logic Apps is a service provided on the Azure cloud platform that enables you to run automated workflows using either code or design blocks. It harnesses the power of serverless apps, where only the business logic is important without worrying about concerns such as scalability, availability, and reliability.
This blog focuses on how to deploy an Azure Logic App using Terraform scripts. The blog will explain in detail how to deploy the logic app using Terraform, along with a few advanced concepts.
The workflow of the logic app is straightforward. It notifies a specific user via email when a new article is published to a particular RSS feed. The workflow is represented in the following diagram when viewed in the designer view on the Azure Portal. However, instead of using Microsoft 365 Outlook, this article uses Gmail to describe how to configure a Gmail API connection for a logic app.
This logic app requires four resources to be created using Terraform.
- Resource Group
- API connection for RSS feed
- API connection for Gmail
- Logic App Workflow
Azure offers the AzureRM Terraform provider, which supports most Azure resources. However, this provider does not expose many configurations for API connections and Logic App workflows. Until recently, developers had to use Azure Resource Manager templates (ARM templates) to deploy these resources. Although ARM templates can be deployed using Terraform, Azure has now introduced another provider called azapi that supports the deployment of API connections, Logic App workflows, and even Azure workbooks. According to Microsoft's Learn Documentation, developers should use azapi as the Terraform provider to provision these resources. Therefore, this blog also uses the azapi provider for API connections and the Logic App workflow, while the AzureRM provider is used to create the resource group.
While the azapi provider allows for the provisioning of API connections using Terraform, the Gmail connection still needs manual authorization through the portal. Moreover, if the Logic App workflow references an unauthorized API connection, it will not be provisioned, causing the terraform apply to fail at the Logic App stage.
To overcome these issues, a layering method can be added to the Terraform script. The creation of the resource group and API connections can be included in one layer, while the Logic App workflow can be included in another layer. The API connections created by the first layer can be manually authorized before running terraform apply in the second layer. This way, the manual authorization can be done without failing the Terraform script.
The codebase explained in this blog can be found here.
It has two layers separated, and each layer has its own set of variables and requires providers in the variables.tf and versions.tf files separately. The Terraform states (.tfstate files) for each layer are stored in separate containers in a storage account as remote backends. This way, the dependencies between layer 1 and layer 2 can be configured using the output variables of layer 1.
To deploy the project, you must first create a storage account within the Azure subscription you intend to use and create two containers in that storage account named layer-1 and layer-2. Then, obtain the access key to the storage account.
Deploy Layer 1:
- Configure the default values in thevariables.tflocated in the layer-1 directory.
- Configure the remote backend details in the file located in the same directory.
- Run terraform init inside the layer-1 directory.
- Run terraform apply If there are no issues in the plan prompted by Terraform, accept it by typing "yes" and pressing Enter. Layer 1 should deploy successfully.
Authorize the Gmail API Connection:
After examining the newly created resources in the Azure Portal, you may notice that the RSS API connection is in a "Connected" status, but the Gmail API connection is in an "Error" state. To authorize it manually, go to the "Edit API Connection" option and click on the "Authorize" button. You will be prompted to log in to your Google account or select one from a list of accounts you’re already logged in to. After logging in, allow the Logic App to use the Gmail permissions and click "Save." You should now see the Gmail API connection in a "Connected" status as well.
Deploy Layer 2
- Configure the default values in the variables.tf file located in the layer-2 directory.
- Configure the remote backend details in the versions.tf file located in the same directory.
- Run terraform init inside the layer-2 directory.
- Run terraform apply. If there are no issues with the plan prompted by Terraform, accept it by typing "yes" and pressing "Enter". Layer 2 should deploy successfully.
- And now, if you head over to the Azure Portal and examine the newly created logic app, you may notice that it has been deployed with no errors, and soon you will receive emails of the newly published RSS feed items through your logic app.
Putting configuration details such as subscription_id, tenant_id, and backend_key in variables.tf and versions.tf f is not a good practice considering the security of the deployment. However, this aspect will not be discussed in this article as it is beyond the scope. The best practice is to use a separate conf file for each layer and separate scripts to run resource creation and destruction, rather than running terraform init , terraform apply, and terraform destroy manually. More details on this can be found here.
If the logic app workflow is no longer wanted and needs to be destroyed, the annihilation process of the layers has to be adhered to the order of last to first. Otherwise, the destroy process will fail because layer 2 is using the outputs from layer 1. To destroy layer 2, navigate to the directory layer 2 and run terraform destroy. To destroy layer 1, navigate to the directory layer 1 and run the same command.
This article focuses mainly on deploying a Logic App workflow using Terraform. It explains the use of azapi Terraform provider to create API connections and Logic App workflows. Additionally, it explains the split of the Terraform script into layers when it involves a manual step in the middle of deployment.