pulumi-django-azure 1.0.16__tar.gz → 1.0.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pulumi-django-azure might be problematic. Click here for more details.

@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pulumi-django-azure
3
- Version: 1.0.16
3
+ Version: 1.0.18
4
4
  Summary: Simply deployment of Django on Azure with Pulumi
5
5
  Author-email: Maarten Ureel <maarten@youreal.eu>
6
6
  License: MIT License
@@ -33,9 +33,9 @@ Classifier: Programming Language :: Python :: 3
33
33
  Requires-Python: >=3.9
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
- Requires-Dist: pulumi>=3.99.0
37
- Requires-Dist: pulumi-azure-native>=2.24.0
38
- Requires-Dist: pulumi-random>=4.14.0
36
+ Requires-Dist: pulumi>=3.146.0
37
+ Requires-Dist: pulumi-azure-native>=2.82.0
38
+ Requires-Dist: pulumi-random>=4.17.0
39
39
 
40
40
  # Pulumi Django Deployment
41
41
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pulumi-django-azure"
7
- version = "1.0.16"
7
+ version = "1.0.18"
8
8
  description = "Simply deployment of Django on Azure with Pulumi"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Maarten Ureel", email = "maarten@youreal.eu" }]
@@ -16,9 +16,9 @@ classifiers = [
16
16
  ]
17
17
  keywords = ["django", "pulumi", "azure"]
18
18
  dependencies = [
19
- "pulumi >= 3.99.0",
20
- "pulumi-azure-native >= 2.24.0",
21
- "pulumi-random >= 4.14.0",
19
+ "pulumi (>=3.146.0)",
20
+ "pulumi-azure-native (>=2.82.0)",
21
+ "pulumi-random (>=4.17.0)",
22
22
  ]
23
23
  requires-python = ">=3.9"
24
24
 
@@ -27,20 +27,20 @@ Homepage = "https://gitlab.com/MaartenUreel/pulumi-django-azure"
27
27
 
28
28
  [tool.poetry]
29
29
  name = "pulumi-django-azure"
30
- version = "1.0.16"
30
+ version = "1.0.18"
31
31
  description = "Simply deployment of Django on Azure with Pulumi"
32
32
  authors = ["Maarten Ureel <maarten@youreal.eu>"]
33
33
 
34
34
  [tool.poetry.dependencies]
35
35
  python = "^3.11"
36
- pulumi-azure-native = "^2.64.2"
37
- pulumi = "^3.135.0"
38
- pulumi-random = "^4.16.6"
36
+ pulumi-azure-native = ">=2.82.0"
37
+ pulumi = ">=3.146.0"
38
+ pulumi-random = ">=4.17.0"
39
39
 
40
40
  [tool.poetry.group.dev.dependencies]
41
- twine = "^5.1.1"
42
- build = "^1.2.2"
43
- ruff = "^0.4.9"
41
+ twine = "^6.0.1"
42
+ build = "^1.2.2.post1"
43
+ ruff = "^0.9.2"
44
44
 
45
45
  [tool.ruff]
46
46
  line-length = 140
@@ -65,12 +65,14 @@ class DjangoDeployment(pulumi.ComponentResource):
65
65
  vnet: azure.network.VirtualNetwork,
66
66
  pgsql_sku: azure.dbforpostgresql.SkuArgs,
67
67
  pgsql_ip_prefix: str,
68
- appservice_ip_prefix: str,
68
+ app_service_ip_prefix: str,
69
69
  app_service_sku: azure.web.SkuDescriptionArgs,
70
70
  storage_account_name: str,
71
71
  storage_allowed_origins: Optional[Sequence[str]] = None,
72
72
  pgadmin_access_ip: Optional[Sequence[str]] = None,
73
73
  pgadmin_dns_zone: Optional[azure.network.Zone] = None,
74
+ cache_ip_prefix: Optional[str] = None,
75
+ cache_sku: Optional[azure.cache.SkuArgs] = None,
74
76
  cdn_host: Optional[HostDefinition] = None,
75
77
  opts=None,
76
78
  ):
@@ -83,12 +85,14 @@ class DjangoDeployment(pulumi.ComponentResource):
83
85
  :param vnet: The virtual network to create the subnets in.
84
86
  :param pgsql_sku: The SKU for the PostgreSQL server.
85
87
  :param pgsql_ip_prefix: The IP prefix for the PostgreSQL subnet.
86
- :param appservice_ip_prefix: The IP prefix for the app service subnet.
88
+ :param app_service_ip_prefix: The IP prefix for the app service subnet.
87
89
  :param app_service_sku: The SKU for the app service plan.
88
90
  :param storage_account_name: The name of the storage account. Should be unique across Azure.
89
91
  :param storage_allowed_origins: The origins (hosts) to allow access through CORS policy. You can specify '*' to allow all.
90
92
  :param pgadmin_access_ip: The IP addresses to allow access to pgAdmin. If empty, all IP addresses are allowed.
91
93
  :param pgadmin_dns_zone: The Azure DNS zone to a pgadmin DNS record in. (optional)
94
+ :param cache_ip_prefix: The IP prefix for the cache subnet. (optional)
95
+ :param cache_sku: The SKU for the cache. (optional)
92
96
  :param cdn_host: A custom CDN host name. (optional)
93
97
  :param opts: The resource options
94
98
  """
@@ -110,10 +114,16 @@ class DjangoDeployment(pulumi.ComponentResource):
110
114
  # PostgreSQL resources
111
115
  self._create_database(sku=pgsql_sku, ip_prefix=pgsql_ip_prefix)
112
116
 
117
+ # Cache resources
118
+ if cache_ip_prefix and cache_sku:
119
+ self._create_cache(sku=cache_sku, ip_prefix=cache_ip_prefix)
120
+ else:
121
+ self._cache = None
122
+
113
123
  # Subnet for the apps
114
124
  self._app_subnet = self._create_subnet(
115
125
  name="app-service",
116
- prefix=appservice_ip_prefix,
126
+ prefix=app_service_ip_prefix,
117
127
  delegation_service="Microsoft.Web/serverFarms",
118
128
  service_endpoints=["Microsoft.Storage"],
119
129
  )
@@ -299,6 +309,85 @@ class DjangoDeployment(pulumi.ComponentResource):
299
309
 
300
310
  pulumi.export("pgsql_host", self._pgsql.fully_qualified_domain_name)
301
311
 
312
+ def _create_cache(self, sku: azure.cache.SkuArgs, ip_prefix: str):
313
+ # Create a Redis cache
314
+ self._cache = azure.cache.Redis(
315
+ f"cache-{self._name}",
316
+ resource_group_name=self._rg,
317
+ sku=sku,
318
+ enable_non_ssl_port=False,
319
+ public_network_access=azure.cache.PublicNetworkAccess.DISABLED,
320
+ )
321
+
322
+ # Create an access policy that gives us access to the cache
323
+ self._cache_access_policy = azure.cache.AccessPolicy(
324
+ f"cache-access-policy-{self._name}",
325
+ resource_group_name=self._rg,
326
+ cache_name=self._cache.name,
327
+ # Same as the built in Data Contributor policy
328
+ permissions="+@all -@dangerous +cluster|info +cluster|nodes +cluster|slots allkeys",
329
+ )
330
+
331
+ # Allocate a subnet for the cache
332
+ subnet = self._create_subnet(
333
+ name="cache",
334
+ prefix=ip_prefix,
335
+ )
336
+
337
+ # Create a private DNS zone for the cache
338
+ dns = azure.network.PrivateZone(
339
+ f"dns-cache-{self._name}",
340
+ resource_group_name=self._rg,
341
+ location="global",
342
+ private_zone_name="privatelink.redis.cache.windows.net",
343
+ )
344
+
345
+ # Link the private DNS zone to the VNet in order to make resolving work
346
+ azure.network.VirtualNetworkLink(
347
+ f"vnet-link-cache-{self._name}",
348
+ resource_group_name=self._rg,
349
+ location="global",
350
+ private_zone_name=dns.name,
351
+ virtual_network=azure.network.SubResourceArgs(id=self._vnet.id),
352
+ registration_enabled=True,
353
+ )
354
+
355
+ # Create a private endpoint for the cache
356
+ endpoint = azure.network.PrivateEndpoint(
357
+ f"private-endpoint-cache-{self._name}",
358
+ resource_group_name=self._rg,
359
+ subnet=azure.network.SubnetArgs(id=subnet.id),
360
+ custom_network_interface_name=f"nic-cache-{self._name}",
361
+ private_link_service_connections=[
362
+ azure.network.PrivateLinkServiceConnectionArgs(
363
+ name=f"pls-cache-{self._name}",
364
+ private_link_service_id=self._cache.id,
365
+ group_ids=["redisCache"],
366
+ )
367
+ ],
368
+ )
369
+
370
+ # Get the private IP address of the endpoint NIC
371
+ ip = endpoint.network_interfaces.apply(
372
+ lambda nics: azure.network.get_network_interface(
373
+ network_interface_name=nics[0].id.split("/")[-1],
374
+ resource_group_name=self._rg,
375
+ )
376
+ .ip_configurations[0]
377
+ .private_ip_address
378
+ )
379
+
380
+ # Create a DNS record for the cache
381
+ azure.network.PrivateRecordSet(
382
+ f"dns-a-cache-{self._name}",
383
+ resource_group_name=self._rg,
384
+ private_zone_name=dns.name,
385
+ relative_record_set_name=self._cache.name,
386
+ record_type="A",
387
+ ttl=300,
388
+ a_records=[azure.network.ARecordArgs(ipv4_address=ip)],
389
+ )
390
+
302
391
  def _create_subnet(
303
392
  self,
304
393
  name,
@@ -329,7 +418,8 @@ class DjangoDeployment(pulumi.ComponentResource):
329
418
  resource_group_name=self._rg,
330
419
  virtual_network_name=self._vnet.name,
331
420
  address_prefix=prefix,
332
- delegations=[delegation_service],
421
+ # We cannot pass an empty list to the delegations parameter, so either list or None
422
+ delegations=[delegation_service] if delegation_service else None,
333
423
  service_endpoints=service_endpoints,
334
424
  )
335
425
 
@@ -562,7 +652,7 @@ class DjangoDeployment(pulumi.ComponentResource):
562
652
 
563
653
  # DKIM records (two CNAME records)
564
654
  for record in ("d_kim", "d_kim2"):
565
- if host.host == "@":
655
+ if host.host == "@": # noqa: SIM108
566
656
  relative_record_set_name = records[record]["name"]
567
657
  else:
568
658
  relative_record_set_name = f"{records[record]['name']}.{host.host}"
@@ -751,7 +841,9 @@ class DjangoDeployment(pulumi.ComponentResource):
751
841
  secrets: Optional[dict[str, str]] = None,
752
842
  comms_data_location: Optional[str] = None,
753
843
  comms_domains: Optional[list[HostDefinition]] = None,
844
+ dedicated_app_service_sku: Optional[azure.web.SkuDescriptionArgs] = None,
754
845
  vault_administrators: Optional[list[str]] = None,
846
+ cache_db: Optional[int] = None,
755
847
  ) -> azure.web.WebApp:
756
848
  """
757
849
  Create a Django website with it's own database and storage containers.
@@ -768,7 +860,9 @@ class DjangoDeployment(pulumi.ComponentResource):
768
860
  and the name of the secret in the Key Vault.
769
861
  :param comms_data_location: The data location for the Communication Services (optional if you don't need it).
770
862
  :param comms_domains: The list of custom domains for the E-mail Communication Services (optional).
771
- :param vault_administrator: The principal ID of the vault administrator (optional).
863
+ :param dedicated_app_service_sku: The SKU for the dedicated App Service Plan (optional).
864
+ :param vault_administrators: The principal IDs of the vault administrators (optional).
865
+ :param cache_db: The index of the cache database to use (optional).
772
866
  """
773
867
 
774
868
  # Create a database
@@ -817,6 +911,12 @@ class DjangoDeployment(pulumi.ComponentResource):
817
911
  s = self._add_webapp_secret(vault, env_name, config_name, f"{name}-{self._name}")
818
912
  environment_variables[f"{env_name}_SECRET_NAME"] = s.name
819
913
 
914
+ # Cache
915
+ if self._cache and cache_db:
916
+ environment_variables["REDIS_CACHE_HOST"] = self._cache.host_name
917
+ environment_variables["REDIS_CACHE_PORT"] = self._cache.ssl_port.apply(lambda port: str(port))
918
+ environment_variables["REDIS_CACHE_DB"] = str(cache_db)
919
+
820
920
  # Create a Django Secret Key (random)
821
921
  secret_key = pulumi_random.RandomString(f"django-secret-{name}-{self._name}", length=50)
822
922
 
@@ -831,10 +931,22 @@ class DjangoDeployment(pulumi.ComponentResource):
831
931
 
832
932
  allowed_hosts = pulumi.Output.concat(*[pulumi.Output.concat(host.full_host, ",") for host in website_hosts])
833
933
 
934
+ # Create a dedicated App Service Plan if requested
935
+ if dedicated_app_service_sku:
936
+ app_service_plan = azure.web.AppServicePlan(
937
+ f"asp-{self._name}-{name}",
938
+ resource_group_name=self._rg,
939
+ kind="Linux",
940
+ reserved=True,
941
+ sku=dedicated_app_service_sku,
942
+ )
943
+ else:
944
+ app_service_plan = self._app_service_plan
945
+
834
946
  app = azure.web.WebApp(
835
947
  f"app-{name}-{self._name}",
836
948
  resource_group_name=self._rg,
837
- server_farm_id=self._app_service_plan.id,
949
+ server_farm_id=app_service_plan.id,
838
950
  virtual_network_subnet_id=self._app_subnet.id,
839
951
  identity=azure.web.ManagedServiceIdentityArgs(
840
952
  type=azure.web.ManagedServiceIdentityType.SYSTEM_ASSIGNED,
@@ -863,14 +975,8 @@ class DjangoDeployment(pulumi.ComponentResource):
863
975
  # Vault settings
864
976
  azure.web.NameValuePairArgs(name="AZURE_KEY_VAULT", value=vault.name),
865
977
  # Storage settings
866
- azure.web.NameValuePairArgs(
867
- name="AZURE_STORAGE_ACCOUNT_NAME",
868
- value=self._storage_account.name,
869
- ),
870
- azure.web.NameValuePairArgs(
871
- name="AZURE_STORAGE_CONTAINER_STATICFILES",
872
- value=static_container.name,
873
- ),
978
+ azure.web.NameValuePairArgs(name="AZURE_STORAGE_ACCOUNT_NAME", value=self._storage_account.name),
979
+ azure.web.NameValuePairArgs(name="AZURE_STORAGE_CONTAINER_STATICFILES", value=static_container.name),
874
980
  azure.web.NameValuePairArgs(name="AZURE_STORAGE_CONTAINER_MEDIA", value=media_container.name),
875
981
  # CDN
876
982
  azure.web.NameValuePairArgs(name="CDN_HOST", value=self._cdn_host),
@@ -1010,6 +1116,17 @@ class DjangoDeployment(pulumi.ComponentResource):
1010
1116
  scope=self._storage_account.id,
1011
1117
  )
1012
1118
 
1119
+ # Grant the app access to the cache if needed
1120
+ if self._cache and cache_db:
1121
+ azure.cache.AccessPolicyAssignment(
1122
+ f"ra-{name}-cache",
1123
+ resource_group_name=self._rg,
1124
+ cache_name=self._cache.name,
1125
+ object_id=principal_id,
1126
+ object_id_alias=f"app-{name}-managed-identity",
1127
+ access_policy_name=self._cache_access_policy.name,
1128
+ )
1129
+
1013
1130
  # Grant the app to send e-mails
1014
1131
  if comms:
1015
1132
  comms_role = comms.id.apply(
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: pulumi-django-azure
3
- Version: 1.0.16
3
+ Version: 1.0.18
4
4
  Summary: Simply deployment of Django on Azure with Pulumi
5
5
  Author-email: Maarten Ureel <maarten@youreal.eu>
6
6
  License: MIT License
@@ -33,9 +33,9 @@ Classifier: Programming Language :: Python :: 3
33
33
  Requires-Python: >=3.9
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
- Requires-Dist: pulumi>=3.99.0
37
- Requires-Dist: pulumi-azure-native>=2.24.0
38
- Requires-Dist: pulumi-random>=4.14.0
36
+ Requires-Dist: pulumi>=3.146.0
37
+ Requires-Dist: pulumi-azure-native>=2.82.0
38
+ Requires-Dist: pulumi-random>=4.17.0
39
39
 
40
40
  # Pulumi Django Deployment
41
41
 
@@ -0,0 +1,3 @@
1
+ pulumi>=3.146.0
2
+ pulumi-azure-native>=2.82.0
3
+ pulumi-random>=4.17.0
@@ -1,3 +0,0 @@
1
- pulumi>=3.99.0
2
- pulumi-azure-native>=2.24.0
3
- pulumi-random>=4.14.0