Skip to content

Commit c97c06b

Browse files
committed
New terraform quickstart for DPS
1 parent d68947e commit c97c06b

File tree

2 files changed

+378
-0
lines changed

2 files changed

+378
-0
lines changed
Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
---
2+
title: Quickstart - Use Terraform to create a DPS instance
3+
description: Learn how to deploy an Azure IoT Device Provisioning Service (DPS) resource with Terraform in this quickstart.
4+
keywords: azure, devops, terraform, device provisioning service, DPS, IoT, IoT Hub DPS
5+
ms.topic: quickstart
6+
ms.date: 09/27/2022
7+
ms.custom: devx-track-terraform
8+
author: kgremban
9+
ms.author: kgremban
10+
ms.service: iot-dps
11+
services: iot-dps
12+
---
13+
14+
# Quickstart: Use Terraform to create an Azure IoT Device Provisioning Service
15+
16+
In this quickstart, you will learn how to deploy an Azure IoT Hub Device Provisioning Service (DPS) resource with a hashed allocation policy using Terraform.
17+
18+
This quickstart was tested with the following Terraform and Terraform provider versions:
19+
20+
- [Terraform v1.2.8](https://releases.hashicorp.com/terraform/)
21+
- [AzureRM Provider v.3.20.0](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs)
22+
23+
[Terraform](https://www.terraform.io/) enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. The [HCL syntax](https://www.terraform.io/language/syntax/configuration) allows you to specify the cloud provider - such as Azure - and the elements that make up your cloud infrastructure. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed. Once you verify the changes, you apply the execution plan to deploy the infrastructure.
24+
25+
In this article, you learn how to:
26+
27+
- Create a Storage Account & Storage Container
28+
- Create an Event Hub, Namespace, & Authorization Rule
29+
- Create an IoT Hub
30+
- Link IoT Hub to Storage Account endpoint & Event Hub endpoint
31+
- Create an IoT Hub Shared Access Policy
32+
- Create a DPS Resource
33+
- Link DPS & IoT Hub
34+
35+
## Prerequisites
36+
37+
- **Azure subscription**: If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F) before you begin.
38+
- [Install and configure Terraform](/azure/developer/terraform/quickstart-configure)
39+
40+
> [!NOTE]
41+
> The example code in this article is located in the [Azure Terraform GitHub repo](https://github.com/Azure/terraform/tree/master/). See more [articles and sample code showing how to use Terraform to manage Azure resources](/azure/developer/terraform/)
42+
43+
## Implement the Terraform code
44+
45+
1. Create a directory in which to test and run the sample Terraform code and make it the current directory.
46+
47+
1. Create a file named `providers.tf` and insert the following code:
48+
49+
[!code-terraform[master](<!-- ~/terraform_samples/<path-to-file>/providers.tf-->)]
50+
51+
```terraform
52+
terraform {
53+
required_version = ">=0.12"
54+
55+
required_providers {
56+
azurerm = {
57+
source = "hashicorp/azurerm"
58+
version = "~>2.0"
59+
}
60+
random = {
61+
source = "hashicorp/random"
62+
version = "~>3.0"
63+
}
64+
}
65+
}
66+
67+
provider "azurerm" {
68+
features {}
69+
}
70+
```
71+
72+
1. Create a file named `main.tf` and insert the following code:
73+
74+
[!code-terraform[master](<!-- ~/terraform_samples/<path-to-file>/main.tf-->)]
75+
76+
```terraform
77+
resource "random_pet" "rg_name" {
78+
prefix = var.resource_group_name_prefix
79+
}
80+
81+
resource "azurerm_resource_group" "rg" {
82+
location = var.resource_group_location
83+
name = random_pet.rg_name.id
84+
}
85+
86+
# Create storage account & container
87+
resource "random_string" "sa_name" {
88+
length = 12
89+
special = false
90+
upper = false
91+
}
92+
93+
resource "azurerm_storage_account" "sa" {
94+
name = random_string.sa_name.id
95+
resource_group_name = azurerm_resource_group.rg.name
96+
location = azurerm_resource_group.rg.location
97+
account_tier = "Standard"
98+
account_replication_type = "LRS"
99+
}
100+
101+
resource "azurerm_storage_container" "my_terraform_container" {
102+
name = "mycontainer"
103+
storage_account_name = azurerm_storage_account.sa.name
104+
container_access_type = "private"
105+
}
106+
107+
108+
# Create an Event Hub & Authorization Rule
109+
resource "random_pet" "eventhubnamespace_name" {
110+
prefix = var.eventhub_namespace_name_prefix
111+
}
112+
113+
resource "azurerm_eventhub_namespace" "namespace" {
114+
name = random_pet.eventhubnamespace_name.id
115+
resource_group_name = azurerm_resource_group.rg.name
116+
location = azurerm_resource_group.rg.location
117+
sku = "Basic"
118+
}
119+
120+
resource "azurerm_eventhub" "my_terraform_eventhub" {
121+
name = "myEventHub"
122+
resource_group_name = azurerm_resource_group.rg.name
123+
namespace_name = azurerm_eventhub_namespace.namespace.name
124+
partition_count = 2
125+
message_retention = 1
126+
}
127+
128+
resource "azurerm_eventhub_authorization_rule" "my_terraform_authorization_rule" {
129+
resource_group_name = azurerm_resource_group.rg.name
130+
namespace_name = azurerm_eventhub_namespace.namespace.name
131+
eventhub_name = azurerm_eventhub.my_terraform_eventhub.name
132+
name = "acctest"
133+
send = true
134+
}
135+
136+
137+
# Create an IoT Hub
138+
resource "random_pet" "iothub_name" {
139+
prefix = var.iothub_name_prefix
140+
length = 1
141+
}
142+
143+
resource "azurerm_iothub" "iothub" {
144+
name = random_pet.iothub_name.id
145+
resource_group_name = azurerm_resource_group.rg.name
146+
location = azurerm_resource_group.rg.location
147+
148+
sku {
149+
name = "S1"
150+
capacity = "1"
151+
}
152+
153+
endpoint {
154+
type = "AzureIotHub.StorageContainer"
155+
connection_string = azurerm_storage_account.sa.primary_blob_connection_string
156+
name = "export"
157+
batch_frequency_in_seconds = 60
158+
max_chunk_size_in_bytes = 10485760
159+
container_name = azurerm_storage_container.my_terraform_container.name
160+
encoding = "Avro"
161+
file_name_format = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}"
162+
}
163+
164+
endpoint {
165+
type = "AzureIotHub.EventHub"
166+
connection_string = azurerm_eventhub_authorization_rule.my_terraform_authorization_rule.primary_connection_string
167+
name = "export2"
168+
}
169+
170+
route {
171+
name = "export"
172+
source = "DeviceMessages"
173+
condition = "true"
174+
endpoint_names = ["export"]
175+
enabled = true
176+
}
177+
178+
route {
179+
name = "export2"
180+
source = "DeviceMessages"
181+
condition = "true"
182+
endpoint_names = ["export2"]
183+
enabled = true
184+
}
185+
186+
enrichment {
187+
key = "tenant"
188+
value = "$twin.tags.Tenant"
189+
endpoint_names = ["export", "export2"]
190+
}
191+
192+
cloud_to_device {
193+
max_delivery_count = 30
194+
default_ttl = "PT1H"
195+
feedback {
196+
time_to_live = "PT1H10M"
197+
max_delivery_count = 15
198+
lock_duration = "PT30S"
199+
}
200+
}
201+
202+
tags = {
203+
purpose = "testing"
204+
}
205+
}
206+
207+
#Create IoT Hub Access Policy
208+
resource "azurerm_iothub_shared_access_policy" "hubaccesspolicy" {
209+
name = "terraform-policy"
210+
resource_group_name = azurerm_resource_group.rg.name
211+
iothub_name = azurerm_iothub.iothub.name
212+
213+
registry_read = true
214+
registry_write = true
215+
service_connect = true
216+
}
217+
218+
# Create IoT Hub DPS
219+
resource "random_pet" "dps_name" {
220+
prefix = var.dps_name_prefix
221+
length = 1
222+
}
223+
224+
resource "azurerm_iothub_dps" "dps" {
225+
name = random_pet.dps_name.id
226+
resource_group_name = azurerm_resource_group.rg.name
227+
location = azurerm_resource_group.rg.location
228+
allocation_policy = "Hashed"
229+
230+
sku {
231+
name = "S1"
232+
capacity = "1"
233+
}
234+
235+
linked_hub {
236+
connection_string = azurerm_iothub_shared_access_policy.hubaccesspolicy.primary_connection_string
237+
location = azurerm_resource_group.rg.location
238+
allocation_weight = 150
239+
apply_allocation_policy = true
240+
}
241+
}
242+
```
243+
244+
1. Create a file named `variables.tf` and insert the following code:
245+
246+
```terraform
247+
variable "resource_group_location" {
248+
default = "eastus"
249+
description = "Location of the resource group."
250+
}
251+
252+
variable "resource_group_name_prefix" {
253+
default = "rg"
254+
description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
255+
}
256+
257+
variable "storage_account_name_prefix" {
258+
default = "sa"
259+
description = "Prefix of the storage account name that's combined with a random ID so name is unique in your Azure subscription."
260+
}
261+
262+
variable "eventhub_namespace_name_prefix" {
263+
default = "namespace"
264+
description = "Prefix of the event hub namespace name that's combined with a random ID so name is unique in your Azure subscription."
265+
}
266+
267+
variable "iothub_name_prefix" {
268+
default = "iothub"
269+
description = "Prefix of the iot hub name that's combined with a random ID so name is unique in your Azure subscription."
270+
}
271+
272+
variable "dps_name_prefix" {
273+
default = "dps"
274+
description = "Prefix of the dps name that's combined with a random ID so name is unique in your Azure subscription."
275+
}
276+
```
277+
278+
1. Create a file named `outputs.tf` and insert the following code:
279+
280+
```terraform
281+
output "azurerm_iothub_name" {
282+
value = azurerm_iothub.iothub.name
283+
}
284+
285+
output "azurerm_iothub_dps_name" {
286+
value = azurerm_iothub_dps.dps.name
287+
}
288+
289+
output "resource_group_name" {
290+
value = azurerm_resource_group.rg.name
291+
}
292+
```
293+
294+
## Initialize Terraform
295+
296+
Run [terraform init](https://www.terraform.io/cli/commands/init) to initialize the Terraform deployment. This command downloads the Azure modules required to manage your Azure resources.
297+
298+
```cmd
299+
terraform init
300+
```
301+
302+
## Create a Terraform execution plan
303+
304+
Run [terraform plan](https://www.terraform.io/cli/commands/plan) to create an execution plan.
305+
306+
```cmd
307+
terraform plan -out main.tfplan
308+
```
309+
310+
The `terraform plan` command creates an execution plan, but doesn't execute it. Instead, it determines what actions are necessary to create the configuration specified in your configuration files. This pattern allows you to verify whether the execution plan matches your expectations before making any changes to actual resources.
311+
312+
The optional `-out` parameter allows you to specify an output file for the plan. Using the `-out` parameter ensures that the plan you reviewed is exactly what is applied.
313+
314+
To read more about persisting execution plans and security, see the [security warning section](https://www.terraform.io/cli/commands/plan#security-warning).
315+
316+
## Apply a Terraform execution plan
317+
318+
Run [terraform apply](https://www.terraform.io/cli/commands/apply) to apply the execution plan to your cloud infrastructure.
319+
320+
```cmd
321+
terraform apply main.tfplan
322+
```
323+
324+
The `terraform apply` command above assumes you previously ran `terraform plan -out main.tfplan`.
325+
326+
If you specified a different filename for the `-out` parameter, use that same filename in the call to `terraform apply`. If you didn't use the `-out` parameter, call `terraform apply` without any parameters.
327+
328+
## Verify the results
329+
330+
**Azure CLI**
331+
Run [az iot dps show](/cli/azure/iot/dps?view=azure-cli-latest#az-iot-dps-show) to display the Azure DPS resource.
332+
333+
```azurecli
334+
az iot dps show \
335+
--name my_terraform_dps \
336+
--resource-group rg
337+
```
338+
339+
**Azure PowerShell**
340+
Run [Get-AzIoTDeviceProvisioningService](/powershell/module/az.deviceprovisioningservices/get-aziotdeviceprovisioningservice?view=azps-8.3.0) to display the Azure DPS resource.
341+
342+
```powershell
343+
Get-AzIoTDeviceProvisioningService `
344+
-ResourceGroupName "rg" `
345+
-Name "my_terraform_dps"
346+
```
347+
348+
The names of the resource group and the DPS instance are displayed in the terraform apply output. You can also run the [terraform output](https://www.terraform.io/cli/commands/output) command to view these output values.
349+
350+
## Clean up resources
351+
352+
[!INCLUDE [terraform-plan-destroy.md](~/azure-dev-docs-pr/articles/terraform/includes/terraform-plan-destroy.md)]
353+
354+
1. Run [terraform plan](https://www.terraform.io/cli/commands/plan) and specify the `destroy` flag.
355+
356+
```cmd
357+
terraform plan -destroy -out main.destroy.tfplan
358+
```
359+
360+
2. Run [terraform apply](https://www.terraform.io/cli/commands/apply) to apply the execution plan.
361+
362+
```cmd
363+
terraform apply main.destroy.tfplan
364+
```
365+
366+
## Troubleshoot Terraform on Azure
367+
368+
[Troubleshoot common problems when using Terraform on Azure](/azure/developer/terraform/troubleshoot)
369+
370+
## Next steps
371+
372+
Now that you have an instance of the Device Provisioning Service, continue to the next quickstart to provision a simulated device to IoT hub:
373+
374+
> [!div class="nextstepaction"]
375+
> [Quickstart: Provision a simulated symmetric key device](./quick-create-simulated-device-symm-key.md)

articles/iot-dps/toc.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ items:
1717
- name: Bicep
1818
displayName: Resource Manager,ARM,template
1919
href: quick-setup-auto-provision-bicep.md
20+
- name: TerraForm
21+
displayName: Resource Manager, ARM, template
22+
href: quick-setup-auto-provision-terraform.md
2023
- name: ARM template
2124
displayName: Resource Manager
2225
href: quick-setup-auto-provision-rm.md

0 commit comments

Comments
 (0)