I am currently trying to figure out why my python cdktf package is not pulling all the correct azurerm provider imports.
Here is my project structure:
azure_vd
| > imports
| .gitignore
| cdktf.json
| help
| main-test.py
| main.py
| Pipfile
| Pipfile.lock
The steps I have completed:
mkdir cdktf-azure-vd
cd cdktf-azure-vd/
cdktf init --template=python
cdktf provider add "azurerm@~>3.63.0"
Added to the cdktf.json
file "terraformProviders": ["azurerm@~> 3.63.0"],
I then ran cdktf get
which generated the imports
dir. However, I did not see the following classes here:
...
from imports.azurerm import (
AzurermProvider,
VirtualDesktopWorkspace,
VirtualDesktopHostPool,
VirtualDesktopApplicationGroup,
VirtualNetwork,
)
...
So I followed up with pipenv install cdktf-cdktf-provider-azurerm
.
I am not sure what else I am missing, unless the provider class names have changed? Am I setting up this cdktf python project incorrectly? Is there a Pipenv piece I am missing? This is my first time using cdktf, so apologies for any naivety.
The error when I run cdk synth
is as follows:
⠹ Synthesizing
[2023-07-04T18:01:23.074] [ERROR] default - Traceback (most recent call last):
File "/home/mason/Documents/CODE/mason_azure_vd/main.py", line 4, in <module>
[2023-07-04T18:01:23.075] [ERROR] default - from imports.azurerm import (
ERROR: cdktf encountered an error while synthesizing
Synth command: pipenv run python main.py
Error: non-zero exit code 1
Command output on stderr:
Traceback (most recent call last):
File "/home/mason/Documents/CODE/mason_azure_vd/main.py", line 4, in <module>
from imports.azurerm import (
ImportError: cannot import name 'AzurermProvider' from 'imports.azurerm' (/home/mason/Documents/CODE/mason_azure_vd/imports/azurerm/__init__.py)
This makes sense, because I am not seeing AzurermProvider
, VirtualDesktopWorkspace
, VirtualDesktopHostPool
, VirtualDesktopApplicationGroup
, VirtualNetwork
in the imports
directory. However, everything I have searched the past two days, including online examples from Terraform on github, point to these class names being correct ?
For posterity here are is some of my code:
main.py
from constructs import Construct
from cdktf import App, TerraformStack, CloudBackend, NamedCloudWorkspace
from imports.azurerm import (
AzurermProvider,
VirtualDesktopWorkspace,
VirtualDesktopHostPool,
VirtualDesktopApplicationGroup,
VirtualNetwork,
)
class MyStack(TerraformStack):
def __init__(self, scope: Construct, id: str):
super().__init__(scope, id)
# Initialize the Azure provider
AzurermProvider(self, "azure", features=[{}])
# Create a Virtual Network
virtual_network = VirtualNetwork(
self,
"virtual-network",
name="my-vnet",
location="westus2",
resource_group_name="virtual-desktop-resource-group",
address_space=["10.0.0.0/16"],
subnets=[{"name": "default", "address_prefix": "10.0.0.0/24"}],
)
# Create an Azure Virtual Desktop Workspace
workspace = VirtualDesktopWorkspace(
self,
"workspace",
name="virtual-desktop-workspace",
location="westus2",
resource_group_name="virtual-desktop-resource-group",
)
# Create an Azure Virtual Desktop Host Pool
host_pool = VirtualDesktopHostPool(
self,
"host-pool",
name="virtual-desktop-host-pool",
location="westus2",
resource_group_name="virtual-desktop-resource-group",
workspace_id=workspace.id,
friendly_name="Virtual Desktop Host Pool",
type="Pooled",
vm_template="Windows-11",
vm_disk_type="Premium",
vm_disk_size_gb=128,
)
# Create an Azure Virtual Desktop Application Group
application_group = VirtualDesktopApplicationGroup(
self,
"application-group",
name="virtual-desktop-application-group",
location="westus2",
resource_group_name="virtual-desktop-application-group-resource-group",
workspace_id=workspace.id,
host_pool_id=host_pool.id,
friendly_name="Virtual Desktop Application Group",
application_group_type="RemoteApp",
allow_public_access=True,
)
app = App()
stack = MyStack(app, "azure_vd")
CloudBackend(
stack,
hostname="app.terraform.io",
organization="redacted-org",
workspaces=NamedCloudWorkspace("azure_vd_poc"),
)
app.synth()
cdktf.json
{
"language": "python",
"app": "pipenv run python main.py",
"projectId": "redacted project id",
"sendCrashReports": "true",
"terraformProviders": ["azurerm@~> 3.63.0"],
"terraformModules": [],
"codeMakerOutput": "imports",
"context": {
}
}
pipfile
:
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[requires]
python_version = "3.11"
[dev-packages]
black = "*"
[packages]
cdktf-cdktf-provider-azurerm = "~=9.0.2"
output from pipenv graph
:
cdktf-cdktf-provider-azurerm==9.0.2
- cdktf [required: >=0.17.0,<0.18.0, installed: 0.17.0]
- constructs [required: >=10.0.25,<11.0.0, installed: 10.2.68]
- jsii [required: >=1.84.0,<2.0.0, installed: 1.84.0]
- attrs [required: >=21.2,<24.0, installed: 23.1.0]
- cattrs [required: >=1.8,<23.2, installed: 23.1.2]
- attrs [required: >=20, installed: 23.1.0]
- importlib-resources [required: >=5.2.0, installed: 5.12.0]
- publication [required: >=0.0.3, installed: 0.0.3]
- python-dateutil [required: Any, installed: 2.8.2]
- six [required: >=1.5, installed: 1.16.0]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- typing-extensions [required: >=3.7,<5.0, installed: 4.7.1]
- publication [required: >=0.0.3, installed: 0.0.3]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- jsii [required: >=1.79.0,<2.0.0, installed: 1.84.0]
- attrs [required: >=21.2,<24.0, installed: 23.1.0]
- cattrs [required: >=1.8,<23.2, installed: 23.1.2]
- attrs [required: >=20, installed: 23.1.0]
- importlib-resources [required: >=5.2.0, installed: 5.12.0]
- publication [required: >=0.0.3, installed: 0.0.3]
- python-dateutil [required: Any, installed: 2.8.2]
- six [required: >=1.5, installed: 1.16.0]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- typing-extensions [required: >=3.7,<5.0, installed: 4.7.1]
- publication [required: >=0.0.3, installed: 0.0.3]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- constructs [required: >=10.0.0,<11.0.0, installed: 10.2.68]
- jsii [required: >=1.84.0,<2.0.0, installed: 1.84.0]
- attrs [required: >=21.2,<24.0, installed: 23.1.0]
- cattrs [required: >=1.8,<23.2, installed: 23.1.2]
- attrs [required: >=20, installed: 23.1.0]
- importlib-resources [required: >=5.2.0, installed: 5.12.0]
- publication [required: >=0.0.3, installed: 0.0.3]
- python-dateutil [required: Any, installed: 2.8.2]
- six [required: >=1.5, installed: 1.16.0]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- typing-extensions [required: >=3.7,<5.0, installed: 4.7.1]
- publication [required: >=0.0.3, installed: 0.0.3]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- jsii [required: >=1.84.0,<2.0.0, installed: 1.84.0]
- attrs [required: >=21.2,<24.0, installed: 23.1.0]
- cattrs [required: >=1.8,<23.2, installed: 23.1.2]
- attrs [required: >=20, installed: 23.1.0]
- importlib-resources [required: >=5.2.0, installed: 5.12.0]
- publication [required: >=0.0.3, installed: 0.0.3]
- python-dateutil [required: Any, installed: 2.8.2]
- six [required: >=1.5, installed: 1.16.0]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
- typing-extensions [required: >=3.7,<5.0, installed: 4.7.1]
- publication [required: >=0.0.3, installed: 0.0.3]
- typeguard [required: ~=2.13.3, installed: 2.13.3]
packaging==23.1
For posterity I needed to change how my imports were being called. I was able to manually look through the imports
dir and Terraform docs to determine the correct imports and methods.
Here is an example of my update imports and code in main.py
from constructs import Construct
from cdktf import App, TerraformStack, CloudBackend, NamedCloudWorkspace
from imports.azurerm import (
provider,
virtual_desktop_workspace,
virtual_desktop_host_pool,
virtual_desktop_application_group,
virtual_network,
subnet,
)
class MyStack(TerraformStack):
def __init__(self, scope: Construct, id: str):
super().__init__(scope, id)
# Initialize the Azure provider
provider.AzurermProvider(self, "azure", features={})
# Create a Virtual Network
virtual_net = virtual_network.VirtualNetwork(
self,
"virtual-network",
name="my-vnet",
location="westus2",
resource_group_name="virtual-desktop-resource-group",
address_space=["10.0.0.0/16"],
)
# Create the virtual subnet for the virtual network
virtual_subnet = subnet.Subnet(
self,
name="azure-vd-subnet",
resource_group_name="virtual-desktop-resource-group",
virtual_network_name=virtual_net.name,
address_prefixes=["10.0.1.0/24"],
id_="azure-vd-subnet-id",
)
# Create an Azure Virtual Desktop Workspace
workspace = virtual_desktop_workspace.VirtualDesktopWorkspace(
self,
"workspace",
name="virtual-desktop-workspace",
location="westus2",
resource_group_name="virtual-desktop-resource-group",
)
# Create an Azure Virtual Desktop Host Pool
host_pool = virtual_desktop_host_pool.VirtualDesktopHostPool(
self,
"host-pool",
name="virtual-desktop-host-pool",
location="westus2",
resource_group_name="virtual-desktop-resource-group",
friendly_name="Virtual Desktop Host",
type="Personal",
load_balancer_type="Persistent",
)
# Create an Azure Virtual Desktop Application Group
application_group = (
virtual_desktop_application_group.VirtualDesktopApplicationGroup(
self,
"application-group",
name="virtual-desktop-application-group",
type="Desktop",
default_desktop_display_name="azure-vd",
location="westus2",
resource_group_name="virtual-desktop-application-group-resource-group",
host_pool_id=host_pool.id,
friendly_name="Virtual Desktop Application Group",
)
)
app = App()
stack = MyStack(app, "azure_vd")
CloudBackend(
stack,
hostname="app.terraform.io",
organization="redacted",
workspaces=NamedCloudWorkspace("azure_vd_poc"),
)
app.synth()
I am now successfully able to cdktf synth
which is generating the cdktf.out
dir, stacks
dir and manifest.json
correctly.
EDIT:
My initial answer works, but to my understanding it is not completely correct as it is just a "local" import.
The correct way is calling the cdktf_cdktf_provider_azurerm
.
from constructs import Construct
from cdktf import TerraformStack, AzurermBackend
from cdktf_cdktf_provider_azurerm import (
data_azurerm_client_config,
nat_gateway,
nat_gateway_public_ip_association,
network_security_group,
network_security_rule,
provider,
public_ip,
resource_group,
subnet,
subnet_nat_gateway_association,
subnet_network_security_group_association,
virtual_network,
virtual_network_gateway,
)