Skip to content

Commit a2024e4

Browse files
First Commit
1 parent 77c3b6c commit a2024e4

22 files changed

+1694
-45
lines changed

.terraform.lock.hcl

+61
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+242-45
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,254 @@
1-
# Project Name
1+
---
2+
page_type: sample
3+
languages:
4+
- azurecli
5+
- bash
6+
- terraform
7+
- yaml
8+
- json
9+
products:
10+
- azure
11+
- azure-container-apps
12+
- azure-storage
13+
- azure-blob-storage
14+
- azure-storage-accounts
15+
- azure-monitor
16+
- azure-log-analytics
17+
- azure-application-insights
18+
19+
name: Deploy a Dapr application to Azure Container Apps with Terraform and AzAPI Provider
20+
description: This sample shows how to deploy a Dapr application to Azure Container Apps using Terraform modules and the AzAPI Provider.
21+
urlFragment: container-apps-azapi-terraform
22+
---
23+
24+
# Deploy a Dapr application to Azure Container Apps with Terraform and AzAPI Provider
25+
26+
[Dapr](https://dapr.io/) (Distributed Application Runtime) is a runtime that helps you build resilient stateless and stateful microservices. This sample shows how to deploy a [Dapr](https://dapr.io/) application to [Azure Container Apps](https://docs.microsoft.com/en-us/azure/container-apps/overview) using Terraform modules and the [AzAPI Provider](https://registry.terraform.io/providers/azure/azapi/latest/docs) instead of an Azure Resource Manager (ARM) or Bicep template like in the original sample [Tutorial: Deploy a Dapr application to Azure Container Apps with an Azure Resource Manager or Bicep template](https://docs.microsoft.com/en-us/azure/container-apps/microservices-dapr-azure-resource-manager?tabs=bash&pivots=container-apps-bicep).
27+
28+
In this sample you will learn how to:
29+
30+
- Use Terraform and [AzAPI Provider](https://registry.terraform.io/providers/azure/azapi/latest/docs) to deploy an microservice-based application to Azure Contains Apps.
31+
- Create an Azure Blob Storage for use as a [Dapr](https://dapr.io/) state store
32+
- Deploy an [Azure Container Apps environment](https://docs.microsoft.com/en-us/azure/container-apps/environment) to host one or more Azure Container Apps
33+
- Deploy two [Dapr-enabled](https://docs.microsoft.com/en-us/azure/container-apps/dapr-overview?tabs=bicep1%2Cyaml) Azure Container Apps: one that produces orders and one that consumes orders and stores them
34+
- Verify the interaction between the two microservices.
35+
36+
With Azure Container Apps, you get a [fully managed version of the Dapr APIs](./dapr-overview.md) when building microservices. When you use [Dapr](https://dapr.io/) in Azure Container Apps, you can enable sidecars to run next to your microservices that provide a rich set of capabilities. Available Dapr APIs include [Service to Service calls](https://docs.dapr.io/developing-applications/building-blocks/service-invocation/), [Pub/Sub](https://docs.dapr.io/developing-applications/building-blocks/pubsub/), [Event Bindings](https://docs.dapr.io/developing-applications/building-blocks/bindings/), [State Stores](https://docs.dapr.io/developing-applications/building-blocks/state-management/), and [Actors](https://docs.dapr.io/developing-applications/building-blocks/actors/).
37+
38+
In this sample, you deploy the same applications from the Dapr [Hello World](https://github.com/dapr/quickstarts/tree/master/tutorials/hello-world) quickstart.
39+
40+
The application consists of:
41+
42+
- A client (Python) container app to generate messages.
43+
- A service (Node) container app to consume and persist those messages in a state store
44+
45+
The following architecture diagram illustrates the components that make up this tutorial:
46+
47+
![Architecture](./images/azure-container-apps-microservices-dapr.png)
48+
49+
## Prerequisites
50+
51+
- Install [Azure CLI](/cli/azure/install-azure-cli)
52+
- An Azure account with an active subscription is required. If you don't already have one, you can [create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). If you don't have one, create a [free Azure account](https://azure.microsoft.com/free/) before you begin.
53+
- [Visual Studio Code](https://code.visualstudio.com/) installed on one of the [supported platforms](https://code.visualstudio.com/docs/supporting/requirements#_platforms) along with the [HashiCorp Terraform](hhttps://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform).
54+
55+
## What is AzAPI Provider?
56+
57+
The [AzAPI Provider](https://registry.terraform.io/providers/azure/azapi/latest/docs) is a very thin layer on top of the Azure ARM REST APIs. This provider compliments the [AzureRM provider](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) by enabling the management of Azure resources that are not yet or may never be supported in the AzureRM provider such as private/public preview services and features. The [AzAPI provider](https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider) enables you to manage any Azure resource type using any API version. This provider complements the AzureRM provider by enabling the management of new Azure resources and properties (including private preview). For more information, see [Overview of the Terraform AzAPI provider](https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider).
58+
59+
## Terraform modules
60+
61+
This sample contains Terraform modules to create the following resources:
62+
63+
- [Microsoft.OperationalInsights/workspaces](https://docs.microsoft.com/en-us/azure/templates/microsoft.operationalinsights/workspaces): an [Azure Log Analytics](https://docs.microsoft.com/en-us/azure/azure-monitor/logs/log-analytics-workspace-overview) workspace used to collect logs and metrics of the [Azure Container Apps environment](https://docs.microsoft.com/en-us/azure/container-apps/environment).
64+
- [Microsoft.Insights/components](https://docs.microsoft.com/en-us/azure/templates/microsoft.insights/components): an [Azure Application Insights](https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview) used by the Azure Container Apps for logging and distributed tracing.
65+
- [Microsoft.Storage/storageAccounts](https://docs.microsoft.com/en-us/azure/templates/microsoft.storage/storageaccounts): this storage account is used to store state of the Dapr component.
66+
- [Microsoft.App/managedEnvironments](https://docs.microsoft.com/en-us/azure/templates/microsoft.app/managedenvironments): an [Azure Container Apps environment](https://docs.microsoft.com/en-us/azure/container-apps/environment) that will host two Azure Container Apps.
67+
- [Microsoft.App/managedEnvironments/daprComponents](https://docs.microsoft.com/en-us/azure/templates/microsoft.app/managedenvironments/daprcomponents): a [state management Dapr component](https://docs.dapr.io/developing-applications/building-blocks/state-management/state-management-overview/) that hosts the orders created by the service application.
68+
- [Microsoft.App/containerApps](https://docs.microsoft.com/en-us/azure/templates/microsoft.app/containerapps): two dapr-enabled Container Apps: [hello-k8s-node](https://hub.docker.com/r/dapriosamples/hello-k8s-node) and [hello-k8s-python](https://hub.docker.com/r/dapriosamples/hello-k8s-python)
69+
70+
The following table contains the code of the `modules/contains_apps/main.tf` Terraform module used to create the Azure Container Apps environment, Dapr components, and Container Apps
71+
72+
```terraform
73+
terraform {
74+
required_version = ">= 1.0"
75+
required_providers {
76+
azurerm = {
77+
source = "hashicorp/azurerm"
78+
version = "3.3.0"
79+
}
80+
azapi = {
81+
source = "Azure/azapi"
82+
version = "0.4.0"
83+
}
84+
}
85+
experiments = [module_variable_optional_attrs]
86+
}
87+
88+
locals {
89+
module_tag = {
90+
"module" = basename(abspath(path.module))
91+
}
92+
tags = merge(var.tags, local.module_tag)
93+
}
94+
95+
resource "azapi_resource" "managed_environment" {
96+
name = var.managed_environment_name
97+
location = var.location
98+
parent_id = var.resource_group_id
99+
type = "Microsoft.App/managedEnvironments@2022-03-01"
100+
tags = local.tags
101+
102+
body = jsonencode({
103+
properties = {
104+
daprAIInstrumentationKey = var.instrumentation_key
105+
appLogsConfiguration = {
106+
destination = "log-analytics"
107+
logAnalyticsConfiguration = {
108+
customerId = var.workspace_id
109+
sharedKey = var.primary_shared_key
110+
}
111+
}
112+
}
113+
})
114+
115+
lifecycle {
116+
ignore_changes = [
117+
tags
118+
]
119+
}
120+
}
121+
122+
resource "azapi_resource" "daprComponents" {
123+
for_each = {for component in var.dapr_components: component.name => component}
124+
125+
name = each.key
126+
parent_id = azapi_resource.managed_environment.id
127+
type = "Microsoft.App/managedEnvironments/daprComponents@2022-03-01"
128+
129+
body = jsonencode({
130+
properties = {
131+
componentType = each.value.componentType
132+
version = each.value.version
133+
ignoreErrors = each.value.ignoreErrors
134+
initTimeout = each.value.initTimeout
135+
secrets = each.value.secrets
136+
metadata = each.value.metadata
137+
scopes = each.value.scopes
138+
}
139+
})
140+
}
141+
142+
resource "azapi_resource" "container_app" {
143+
for_each = {for app in var.container_apps: app.name => app}
144+
145+
name = each.key
146+
location = var.location
147+
parent_id = var.resource_group_id
148+
type = "Microsoft.App/containerApps@2022-03-01"
149+
tags = local.tags
150+
151+
body = jsonencode({
152+
properties: {
153+
managedEnvironmentId = azapi_resource.managed_environment.id
154+
configuration = {
155+
ingress = try(each.value.configuration.ingress, null)
156+
dapr = try(each.value.configuration.dapr, null)
157+
}
158+
template = each.value.template
159+
}
160+
})
161+
162+
lifecycle {
163+
ignore_changes = [
164+
tags
165+
]
166+
}
167+
}
168+
```
169+
170+
As you can see, the module uses an [azapi_resource](https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider) to create the resources. You can use an [azapi_resource](https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider) to fully manage any Azure (control plane) resource (API) with full CRUD. Example Use Cases:
171+
172+
- New preview service
173+
- New feature added to existing service
174+
- Existing feature / service not currently covered
175+
176+
For more information, see [Overview of the Terraform AzAPI provider](https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider).
177+
178+
## Deploy
179+
180+
You can use the `deploy.sh` bash script to deploy the sample:
181+
182+
```bash
183+
#!/bin/bash
184+
185+
# Terraform Init
186+
terraform init
187+
188+
# Terraform validate
189+
terraform validate -compact-warnings
190+
191+
# Terraform plan
192+
terraform plan -compact-warnings -out main.tfplan
193+
194+
# Terraform apply
195+
terraform apply -compact-warnings -auto-approve main.tfplan
196+
```
197+
This command deploys the Terraform modules that create the following resources:
198+
199+
- The Container Apps environment and associated Log Analytics workspace for hosting the hello world Dapr solution.
200+
- An Application Insights instance for Dapr distributed tracing.
201+
- The `nodeapp` app server running on `targetPort: 3000` with dapr enabled and configured using: `"appId": "nodeapp"` and `"appPort": 3000`.
202+
- The `daprComponents` object of `"type": "state.azure.blobstorage"` scoped for use by the `nodeapp` for storing state.
203+
- The headless `pythonapp` with no ingress and Dapr enabled that calls the `nodeapp` service via dapr service-to-service communication.
204+
205+
## Verify the result
206+
207+
### Confirm successful state persistence
208+
209+
You can confirm that the services are working correctly by viewing data in your Azure Storage account.
210+
211+
1. Open the [Azure portal](https://portal.azure.com) in your browser.
212+
1. Navigate to your storage account.
213+
1. Select **Containers** from the menu on the left side.
214+
1. Select **state**.
215+
1. Verify that you can see the file named `order` in the container.
216+
1. Select on the file.
217+
1. Select the **Edit** tab.
218+
1. Select the **Refresh** button to observe updates.
2219

3-
(short, 1-3 sentenced, description of the project)
220+
### View Logs
4221

5-
## Features
222+
Data logged via a container app are stored in the `ContainerAppConsoleLogs_CL` custom table in the Log Analytics workspace. You can view logs through the Azure portal or from the command line. Wait a few minutes for the analytics to arrive for the first time before you query the logged data.
6223

7-
This project framework provides the following features:
224+
1. Open the [Azure portal](https://portal.azure.com) in your browser.
225+
1. Navigate to your log analytics workspace.
226+
1. Select **Logs** from the menu on the left side.
227+
1. Run the following Kusto query.
8228

9-
* Feature 1
10-
* Feature 2
11-
* ...
229+
```kql
230+
ContainerAppConsoleLogs_CL
231+
| project TimeGenerated, ContainerAppName_s, Log_s
232+
| order by TimeGenerated desc
233+
```
12234

13-
## Getting Started
235+
The following images shows the the type of response to expect from the command.
14236

15-
### Prerequisites
237+
![Logs](./images/logs.png)
16238

17-
(ideally very short, if any)
239+
## Clean up resources
18240

19-
- OS
20-
- Library version
21-
- ...
241+
Once you are done, run the following command to delete your resource group along with all the resources you created in this tutorial.
22242

23-
### Installation
243+
```bash
244+
az group delete \
245+
--resource-group $RESOURCE_GROUP
246+
```
24247

25-
(ideally very short)
248+
Since `pythonapp` continuously makes calls to `nodeapp` with messages that get persisted into your configured state store, it is important to complete these cleanup steps to avoid ongoing billable operations.
26249

27-
- npm install [package name]
28-
- mvn install
29-
- ...
250+
## Next steps
30251

31-
### Quickstart
32-
(Add steps to get up and running quickly)
33-
34-
1. git clone [repository clone url]
35-
2. cd [repository name]
36-
3. ...
37-
38-
39-
## Demo
40-
41-
A demo app is included to show how to use the project.
42-
43-
To run the demo, follow these steps:
44-
45-
(Add steps to start up the demo)
46-
47-
1.
48-
2.
49-
3.
50-
51-
## Resources
52-
53-
(Any additional resources or related projects)
54-
55-
- Link to supporting information
56-
- Link to similar sample
57-
- ...
252+
- [Azure Container Apps overview](https://docs.microsoft.com/en-us/azure/container-apps/overview)
253+
- [Tutorial: Deploy a Dapr application to Azure Container Apps with an Azure Resource Manager or Bicep template](https://docs.microsoft.com/en-us/azure/container-apps/microservices-dapr-azure-resource-manager?tabs=bash&pivots=container-apps-bicep)
254+
[AzAPI provider](https://docs.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider)

deploy.sh

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
# Terraform Init
4+
terraform init
5+
6+
# Terraform validate
7+
terraform validate -compact-warnings
8+
9+
# Terraform plan
10+
terraform plan -compact-warnings -out main.tfplan
11+
12+
# Terraform apply
13+
terraform apply -compact-warnings -auto-approve main.tfplan
Loading

images/logs.png

18.2 KB
Loading

0 commit comments

Comments
 (0)