pulumi-django-azure 1.0.4__py3-none-any.whl → 1.0.10__py3-none-any.whl
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.
- pulumi_django_azure/django_deployment.py +169 -8
- {pulumi_django_azure-1.0.4.dist-info → pulumi_django_azure-1.0.10.dist-info}/METADATA +67 -1
- pulumi_django_azure-1.0.10.dist-info/RECORD +7 -0
- {pulumi_django_azure-1.0.4.dist-info → pulumi_django_azure-1.0.10.dist-info}/WHEEL +1 -1
- pulumi_django_azure-1.0.4.dist-info/RECORD +0 -7
- {pulumi_django_azure-1.0.4.dist-info → pulumi_django_azure-1.0.10.dist-info}/LICENSE +0 -0
- {pulumi_django_azure-1.0.4.dist-info → pulumi_django_azure-1.0.10.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
14
14
|
tenant_id: str,
|
|
15
15
|
resource_group_name: pulumi.Input[str],
|
|
16
16
|
vnet: azure.network.VirtualNetwork,
|
|
17
|
+
pgsql_sku: azure.dbforpostgresql.SkuArgs,
|
|
17
18
|
pgsql_ip_prefix: str,
|
|
18
19
|
appservice_ip_prefix: str,
|
|
19
20
|
app_service_sku: azure.web.SkuDescriptionArgs,
|
|
@@ -28,6 +29,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
28
29
|
:param tenant_id: The Entra tenant ID for the database authentication.
|
|
29
30
|
:param resource_group_name: The resource group name to create the resources in.
|
|
30
31
|
:param vnet: The virtual network to create the subnets in.
|
|
32
|
+
:param pgsql_sku: The SKU for the PostgreSQL server.
|
|
31
33
|
:param pgsql_ip_prefix: The IP prefix for the PostgreSQL subnet.
|
|
32
34
|
:param appservice_ip_prefix: The IP prefix for the app service subnet.
|
|
33
35
|
:param app_service_sku: The SKU for the app service plan.
|
|
@@ -39,6 +41,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
39
41
|
super().__init__("pkg:index:DjangoDeployment", name, None, opts)
|
|
40
42
|
|
|
41
43
|
# child_opts = pulumi.ResourceOptions(parent=self)
|
|
44
|
+
self._config = pulumi.Config()
|
|
42
45
|
|
|
43
46
|
self._name = name
|
|
44
47
|
self._tenant_id = tenant_id
|
|
@@ -50,7 +53,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
50
53
|
self._cdn_host = self._create_cdn(custom_host=cdn_host)
|
|
51
54
|
|
|
52
55
|
# PostgreSQL resources
|
|
53
|
-
self._create_database(ip_prefix=pgsql_ip_prefix)
|
|
56
|
+
self._create_database(sku=pgsql_sku, ip_prefix=pgsql_ip_prefix)
|
|
54
57
|
|
|
55
58
|
# Subnet for the apps
|
|
56
59
|
self._app_subnet = self._create_subnet(
|
|
@@ -145,7 +148,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
145
148
|
# Return the default CDN host name
|
|
146
149
|
return self._cdn_endpoint.host_name
|
|
147
150
|
|
|
148
|
-
def _create_database(self, ip_prefix: str):
|
|
151
|
+
def _create_database(self, sku: azure.dbforpostgresql.SkuArgs, ip_prefix: str):
|
|
149
152
|
# Create subnet for PostgreSQL
|
|
150
153
|
subnet = self._create_subnet(
|
|
151
154
|
name="pgsql",
|
|
@@ -176,10 +179,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
176
179
|
self._pgsql = azure.dbforpostgresql.Server(
|
|
177
180
|
f"pgsql-{self._name}",
|
|
178
181
|
resource_group_name=self._rg,
|
|
179
|
-
sku=
|
|
180
|
-
name="Standard_B2s",
|
|
181
|
-
tier=azure.dbforpostgresql.SkuTier.BURSTABLE,
|
|
182
|
-
),
|
|
182
|
+
sku=sku,
|
|
183
183
|
version="16",
|
|
184
184
|
auth_config=azure.dbforpostgresql.AuthConfigArgs(
|
|
185
185
|
password_auth=azure.dbforpostgresql.PasswordAuthEnum.DISABLED,
|
|
@@ -260,8 +260,6 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
260
260
|
# azure.web.NameValuePairArgs(name="WEBSITE_HTTPLOGGING_RETENTION_DAYS", value="7"),
|
|
261
261
|
# pgAdmin settings
|
|
262
262
|
azure.web.NameValuePairArgs(name="PGADMIN_DISABLE_POSTFIX", value="true"),
|
|
263
|
-
azure.web.NameValuePairArgs(name="PGADMIN_AUTHENTICATION_SOURCES", value="['oauth2, 'internal']"),
|
|
264
|
-
azure.web.NameValuePairArgs(name="PGADMIN_OAUTH2_NAME", value="azure"),
|
|
265
263
|
azure.web.NameValuePairArgs(name="PGADMIN_DEFAULT_EMAIL", value="dbadmin@dbadmin.net"),
|
|
266
264
|
azure.web.NameValuePairArgs(name="PGADMIN_DEFAULT_PASSWORD", value="dbadmin"),
|
|
267
265
|
],
|
|
@@ -348,6 +346,104 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
348
346
|
host_name=host,
|
|
349
347
|
)
|
|
350
348
|
|
|
349
|
+
def _add_webapp_comms(self, data_location: str, domains: list[str], suffix: str) -> azure.communication.CommunicationService:
|
|
350
|
+
email_service = azure.communication.EmailService(
|
|
351
|
+
f"comms-email-{suffix}",
|
|
352
|
+
resource_group_name=self._rg,
|
|
353
|
+
location="global",
|
|
354
|
+
data_location=data_location,
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
domain_resources = []
|
|
358
|
+
if domains:
|
|
359
|
+
# Add our own custom domains
|
|
360
|
+
for domain in domains:
|
|
361
|
+
safe_host = domain.replace(".", "-")
|
|
362
|
+
d = azure.communication.Domain(
|
|
363
|
+
f"comms-email-domain-{suffix}-{safe_host}",
|
|
364
|
+
resource_group_name=self._rg,
|
|
365
|
+
location="global",
|
|
366
|
+
domain_management=azure.communication.DomainManagement.CUSTOMER_MANAGED,
|
|
367
|
+
domain_name=domain,
|
|
368
|
+
email_service_name=email_service.name,
|
|
369
|
+
)
|
|
370
|
+
domain_resources.append(d.id.apply(lambda n: n))
|
|
371
|
+
else:
|
|
372
|
+
# Add an Azure managed domain
|
|
373
|
+
d = azure.communication.Domain(
|
|
374
|
+
f"comms-email-domain-{suffix}-azure",
|
|
375
|
+
resource_group_name=self._rg,
|
|
376
|
+
location="global",
|
|
377
|
+
domain_management=azure.communication.DomainManagement.AZURE_MANAGED,
|
|
378
|
+
domain_name="AzureManagedDomain",
|
|
379
|
+
email_service_name=email_service.name,
|
|
380
|
+
)
|
|
381
|
+
domain_resources.append(d.id.apply(lambda n: n))
|
|
382
|
+
|
|
383
|
+
# Create Communication Services and link the domains
|
|
384
|
+
comm_service = azure.communication.CommunicationService(
|
|
385
|
+
f"comms-{suffix}",
|
|
386
|
+
resource_group_name=self._rg,
|
|
387
|
+
location="global",
|
|
388
|
+
data_location=data_location,
|
|
389
|
+
linked_domains=domain_resources,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
return comm_service
|
|
393
|
+
|
|
394
|
+
def _add_webapp_vault(self, administrators: list[str], suffix: str) -> azure.keyvault.Vault:
|
|
395
|
+
# Create a keyvault
|
|
396
|
+
vault = azure.keyvault.Vault(
|
|
397
|
+
f"vault-{suffix}",
|
|
398
|
+
resource_group_name=self._rg,
|
|
399
|
+
vault_name=f"vault-{suffix}",
|
|
400
|
+
properties=azure.keyvault.VaultPropertiesArgs(
|
|
401
|
+
tenant_id=self._tenant_id,
|
|
402
|
+
sku=azure.keyvault.SkuArgs(
|
|
403
|
+
name=azure.keyvault.SkuName.STANDARD,
|
|
404
|
+
family=azure.keyvault.SkuFamily.A,
|
|
405
|
+
),
|
|
406
|
+
enable_rbac_authorization=True,
|
|
407
|
+
),
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
# Find the Key Vault Administrator role
|
|
411
|
+
administrator_role = vault.id.apply(
|
|
412
|
+
lambda scope: azure.authorization.get_role_definition(
|
|
413
|
+
role_definition_id="00482a5a-887f-4fb3-b363-3b7fe8e74483",
|
|
414
|
+
scope=scope,
|
|
415
|
+
)
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
# Add vault administrators
|
|
419
|
+
for a in administrators:
|
|
420
|
+
azure.authorization.RoleAssignment(
|
|
421
|
+
f"ra-{suffix}-vault-admin-{a}",
|
|
422
|
+
principal_id=a,
|
|
423
|
+
principal_type=azure.authorization.PrincipalType.USER,
|
|
424
|
+
role_definition_id=administrator_role.id,
|
|
425
|
+
scope=vault.id,
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
return vault
|
|
429
|
+
|
|
430
|
+
def _add_webapp_secret(self, vault: azure.keyvault.Vault, secret_name: str, config_secret_name: str, suffix: str):
|
|
431
|
+
secret = self._config.require_secret(config_secret_name)
|
|
432
|
+
|
|
433
|
+
# Normalize the secret name
|
|
434
|
+
secret_name = secret_name.replace("_", "-").lower()
|
|
435
|
+
|
|
436
|
+
# Create a secret in the vault
|
|
437
|
+
return azure.keyvault.Secret(
|
|
438
|
+
f"secret-{suffix}-{secret_name}",
|
|
439
|
+
resource_group_name=self._rg,
|
|
440
|
+
vault_name=vault.name,
|
|
441
|
+
secret_name=secret_name,
|
|
442
|
+
properties=azure.keyvault.SecretPropertiesArgs(
|
|
443
|
+
value=secret,
|
|
444
|
+
),
|
|
445
|
+
)
|
|
446
|
+
|
|
351
447
|
def _get_storage_account_access_keys(
|
|
352
448
|
self, storage_account: azure.storage.StorageAccount
|
|
353
449
|
) -> Sequence[azure.storage.outputs.StorageAccountKeyResponse]:
|
|
@@ -394,6 +490,10 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
394
490
|
website_hosts: list[str],
|
|
395
491
|
django_settings_module: str,
|
|
396
492
|
environment_variables: dict[str, str] = {},
|
|
493
|
+
secrets: dict[str, str] = {},
|
|
494
|
+
comms_data_location: Optional[str] = None,
|
|
495
|
+
comms_domains: Optional[list[str]] = [],
|
|
496
|
+
vault_administrators: Optional[list[str]] = [],
|
|
397
497
|
) -> azure.web.WebApp:
|
|
398
498
|
"""
|
|
399
499
|
Create a Django website with it's own database and storage containers.
|
|
@@ -405,6 +505,12 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
405
505
|
:param website_hosts: The list of custom host names for the website.
|
|
406
506
|
:param django_settings_module: The Django settings module to load.
|
|
407
507
|
:param environment_variables: A dictionary of environment variables to set.
|
|
508
|
+
:param secrets: A dictionary of secrets to store in the Key Vault and assign as environment variables.
|
|
509
|
+
The key is the name of the Pulumi secret, the value is the name of the environment variable
|
|
510
|
+
and the name of the secret in the Key Vault.
|
|
511
|
+
:param comms_data_location: The data location for the Communication Services (optional if you don't need it).
|
|
512
|
+
:param comms_domains: The list of custom domains for the E-mail Communication Services (optional).
|
|
513
|
+
:param vault_administrator: The principal ID of the vault administrator (optional).
|
|
408
514
|
"""
|
|
409
515
|
|
|
410
516
|
# Create a database
|
|
@@ -433,6 +539,22 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
433
539
|
container_name=f"{name}-static",
|
|
434
540
|
)
|
|
435
541
|
|
|
542
|
+
# Communication Services (optional)
|
|
543
|
+
if comms_data_location:
|
|
544
|
+
comms = self._add_webapp_comms(comms_data_location, comms_domains, f"{name}-{self._name}")
|
|
545
|
+
# Add the service endpoint as environment variable
|
|
546
|
+
environment_variables["AZURE_COMMUNICATION_SERVICE_ENDPOINT"] = comms.host_name.apply(lambda host: f"https://{host}")
|
|
547
|
+
else:
|
|
548
|
+
comms = None
|
|
549
|
+
|
|
550
|
+
# Key Vault
|
|
551
|
+
vault = self._add_webapp_vault(vault_administrators, f"{name}-{self._name}")
|
|
552
|
+
|
|
553
|
+
# Add secrets
|
|
554
|
+
for config_name, env_name in secrets.items():
|
|
555
|
+
s = self._add_webapp_secret(vault, env_name, config_name, f"{name}-{self._name}")
|
|
556
|
+
environment_variables[f"{env_name}_SECRET_NAME"] = s.name
|
|
557
|
+
|
|
436
558
|
# Create a Django Secret Key (random)
|
|
437
559
|
secret_key = pulumi_random.RandomString(f"django-secret-{name}-{self._name}", length=50)
|
|
438
560
|
|
|
@@ -455,6 +577,7 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
455
577
|
),
|
|
456
578
|
https_only=True,
|
|
457
579
|
site_config=azure.web.SiteConfigArgs(
|
|
580
|
+
app_command_line="cicd/startup.sh",
|
|
458
581
|
always_on=True,
|
|
459
582
|
health_check_path=self.HEALTH_CHECK_PATH,
|
|
460
583
|
ftps_state=azure.web.FtpsState.DISABLED,
|
|
@@ -473,6 +596,8 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
473
596
|
azure.web.NameValuePairArgs(name="DJANGO_SETTINGS_MODULE", value=django_settings_module),
|
|
474
597
|
azure.web.NameValuePairArgs(name="DJANGO_SECRET_KEY", value=secret_key.result),
|
|
475
598
|
azure.web.NameValuePairArgs(name="DJANGO_ALLOWED_HOSTS", value=",".join(website_hosts)),
|
|
599
|
+
# Vault settings
|
|
600
|
+
azure.web.NameValuePairArgs(name="AZURE_KEY_VAULT", value=vault.name),
|
|
476
601
|
# Storage settings
|
|
477
602
|
azure.web.NameValuePairArgs(name="AZURE_STORAGE_ACCOUNT_NAME", value=self._storage_account.name),
|
|
478
603
|
azure.web.NameValuePairArgs(name="AZURE_STORAGE_CONTAINER_STATICFILES", value=static_container.name),
|
|
@@ -517,6 +642,24 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
517
642
|
f"{name}_deploy_ssh_key_url", app.name.apply(lambda name: f"https://{name}.scm.azurewebsites.net/api/sshkey?ensurePublicKey=1")
|
|
518
643
|
)
|
|
519
644
|
|
|
645
|
+
# Find the role for Key Vault Secrets User
|
|
646
|
+
vault_access_role = vault.id.apply(
|
|
647
|
+
lambda scope: azure.authorization.get_role_definition(
|
|
648
|
+
role_definition_id="4633458b-17de-408a-b874-0445c86b69e6",
|
|
649
|
+
scope=scope,
|
|
650
|
+
)
|
|
651
|
+
)
|
|
652
|
+
|
|
653
|
+
# Grant the app access to the vault
|
|
654
|
+
azure.authorization.RoleAssignment(
|
|
655
|
+
f"ra-{name}-vault-user",
|
|
656
|
+
principal_id=principal_id,
|
|
657
|
+
principal_type=azure.authorization.PrincipalType.SERVICE_PRINCIPAL,
|
|
658
|
+
# Key Vault Secrets User
|
|
659
|
+
role_definition_id=vault_access_role.id,
|
|
660
|
+
scope=vault.id,
|
|
661
|
+
)
|
|
662
|
+
|
|
520
663
|
# Find the role for Storage Blob Data Contributor
|
|
521
664
|
storage_role = self._storage_account.id.apply(
|
|
522
665
|
lambda scope: azure.authorization.get_role_definition(
|
|
@@ -534,6 +677,24 @@ class DjangoDeployment(pulumi.ComponentResource):
|
|
|
534
677
|
scope=self._storage_account.id,
|
|
535
678
|
)
|
|
536
679
|
|
|
680
|
+
# Grant the app to send e-mails
|
|
681
|
+
if comms:
|
|
682
|
+
comms_role = comms.id.apply(
|
|
683
|
+
lambda scope: azure.authorization.get_role_definition(
|
|
684
|
+
# Contributor
|
|
685
|
+
role_definition_id="b24988ac-6180-42a0-ab88-20f7382dd24c",
|
|
686
|
+
scope=scope,
|
|
687
|
+
)
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
azure.authorization.RoleAssignment(
|
|
691
|
+
f"ra-{name}-comms",
|
|
692
|
+
principal_id=principal_id,
|
|
693
|
+
principal_type=azure.authorization.PrincipalType.SERVICE_PRINCIPAL,
|
|
694
|
+
role_definition_id=comms_role.id,
|
|
695
|
+
scope=comms.id,
|
|
696
|
+
)
|
|
697
|
+
|
|
537
698
|
# Create a CORS rules for this website
|
|
538
699
|
if website_hosts:
|
|
539
700
|
origins = [f"https://{host}" for host in website_hosts]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pulumi-django-azure
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
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
|
|
@@ -45,9 +45,23 @@ To have a proper and secure environment, we need these components:
|
|
|
45
45
|
* Storage account for media and static files
|
|
46
46
|
* CDN endpoint in front with a domain name of our choosing
|
|
47
47
|
* PostgreSQL server
|
|
48
|
+
* Azure Communication Services to send e-mails
|
|
48
49
|
* Webapp with multiple custom host names and managed SSL for the website itself
|
|
50
|
+
* Azure Key Vault per application
|
|
49
51
|
* Webapp running pgAdmin
|
|
50
52
|
|
|
53
|
+
## Project requirements
|
|
54
|
+
Your Django project should contain a folder `cicd` with these files:
|
|
55
|
+
* pre_build.sh: commands to be executed before building the application, for example NPM install, CSS build commands,...
|
|
56
|
+
* post_build.sh: commands to be executed after building the application, e.g. cleaning up.
|
|
57
|
+
Note that this runs in the identity of the build container, so you should not run database or storage manipulations here.
|
|
58
|
+
* startup.sh: commands to run the actual application. I recommend to put at least:
|
|
59
|
+
```bash
|
|
60
|
+
python manage.py migrate
|
|
61
|
+
python manage.py collectstatic --noinput
|
|
62
|
+
gunicorn --timeout 600 --workers $((($NUM_CORES*2)+1)) --chdir $APP_PATH yourapplication.wsgi --access-logfile '-' --error-logfile '-'
|
|
63
|
+
```
|
|
64
|
+
Be sure to change `yourapplication` in the above.
|
|
51
65
|
## Installation
|
|
52
66
|
This package is published on PyPi, so you can just add pulumi-django-azure to your requirements file.
|
|
53
67
|
|
|
@@ -101,6 +115,8 @@ django.add_django_website(
|
|
|
101
115
|
repository_branch="main",
|
|
102
116
|
website_hosts=["example.com", "www.example.com"],
|
|
103
117
|
django_settings_module="mywebsite.settings.production",
|
|
118
|
+
comms_data_location="europe",
|
|
119
|
+
comms_domains=["mydomain.com"],
|
|
104
120
|
)
|
|
105
121
|
|
|
106
122
|
django.add_database_administrator(
|
|
@@ -120,6 +136,7 @@ django.add_database_administrator(
|
|
|
120
136
|
6. Re-deploy with custom hosts
|
|
121
137
|
7. Re-deploy once more to enable HTTPS on website domains
|
|
122
138
|
8. Manually activate HTTPS on the CDN host
|
|
139
|
+
9. Go to the e-mail communications service on Azure and configure DKIM, SPF,... for your custom domains.
|
|
123
140
|
|
|
124
141
|
## Custom domain name for CDN
|
|
125
142
|
When deploying the first time, you will get a `cdn_cname` output. You need to create a CNAME to this domain before the deployment of the custom domain will succeed.
|
|
@@ -172,6 +189,55 @@ pgAdmin will be created with a default login:
|
|
|
172
189
|
|
|
173
190
|
Best practice is to log in right away, create a user for yourself and delete this default user.
|
|
174
191
|
|
|
192
|
+
## Azure OAuth2 / Django Social Auth
|
|
193
|
+
If you want to set up login with Azure, which would make sense since you are in the ecosystem, you need to create an App Registration in Entra ID, create a secret and then register these settings in your stack:
|
|
194
|
+
```
|
|
195
|
+
pulumi config set --secret --path 'mywebsite_social_auth_azure.key' secret_ID
|
|
196
|
+
pulumi config set --secret --path 'mywebsite_social_auth_azure.secret' secret_value
|
|
197
|
+
pulumi config set --secret --path 'mywebsite_social_auth_azure.tenant_id' directory_tenant_id
|
|
198
|
+
pulumi config set --secret --path 'mywebsite_social_auth_azure.client_id' application_id
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Then in your Django deployment, pass to the `add_django_website` command:
|
|
202
|
+
```
|
|
203
|
+
secrets={
|
|
204
|
+
"mywebsite_social_auth_azure": "AZURE_OAUTH",
|
|
205
|
+
},
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The value will be automatically stored in the vault where the application has access to.
|
|
209
|
+
The environment variable will be suffixed with `_SECRET_NAME`.
|
|
210
|
+
|
|
211
|
+
Then, in your application, retrieve this data from the vault, e.g.:
|
|
212
|
+
```python
|
|
213
|
+
from azure.keyvault.secrets import SecretClient
|
|
214
|
+
from azure.identity import DefaultAzureCredential
|
|
215
|
+
|
|
216
|
+
# Azure credentials
|
|
217
|
+
azure_credential = DefaultAzureCredential()
|
|
218
|
+
|
|
219
|
+
# Azure Key Vault
|
|
220
|
+
AZURE_KEY_VAULT = env("AZURE_KEY_VAULT")
|
|
221
|
+
AZURE_KEY_VAULT_URI = f"https://{AZURE_KEY_VAULT}.vault.azure.net"
|
|
222
|
+
azure_key_vault_client = SecretClient(vault_url=AZURE_KEY_VAULT_URI, credential=azure_credential)
|
|
223
|
+
|
|
224
|
+
# Social Auth settings
|
|
225
|
+
oauth_secret = azure_key_vault_client.get_secret(env("AZURE_OAUTH_SECRET_NAME"))
|
|
226
|
+
oauth_secret = json.loads(oauth_secret.value)
|
|
227
|
+
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY = oauth_secret["client_id"]
|
|
228
|
+
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET = oauth_secret["secret"]
|
|
229
|
+
SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID = oauth_secret["tenant_id"]
|
|
230
|
+
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ["username", "first_name", "last_name", "email"]
|
|
231
|
+
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
|
|
232
|
+
|
|
233
|
+
AUTHENTICATION_BACKENDS = (
|
|
234
|
+
"social_core.backends.azuread_tenant.AzureADTenantOAuth2",
|
|
235
|
+
"django.contrib.auth.backends.ModelBackend",
|
|
236
|
+
)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
And of course add the login button somewhere, following Django Social Auth instructions.
|
|
240
|
+
|
|
175
241
|
## Automate deployments
|
|
176
242
|
When using a service like GitLab, you can configure a Webhook to fire upon a push to your branch.
|
|
177
243
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pulumi_django_azure/__init__.py,sha256=tXTvPfr8-Nll5cjMyY9yj_0z_PQ0XAcxihzHRCES-hU,63
|
|
2
|
+
pulumi_django_azure/django_deployment.py,sha256=SgMLoQ2Jwm8anADzrEjVhtfJVAJrYJYFoaOL9bDZngE,30275
|
|
3
|
+
pulumi_django_azure-1.0.10.dist-info/LICENSE,sha256=NX2LN3U319Zaac8b7ZgfNOco_nTBbN531X_M_13niSg,1087
|
|
4
|
+
pulumi_django_azure-1.0.10.dist-info/METADATA,sha256=rAAqdkW9F0I0OWn7XQA2fHKIpqxmJDQWx39TmH0FEnc,11083
|
|
5
|
+
pulumi_django_azure-1.0.10.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
6
|
+
pulumi_django_azure-1.0.10.dist-info/top_level.txt,sha256=MNPRJhq-_G8EMCHRkjdcb_xrqzOkmKogXUGV7Ysz3g0,20
|
|
7
|
+
pulumi_django_azure-1.0.10.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
pulumi_django_azure/__init__.py,sha256=tXTvPfr8-Nll5cjMyY9yj_0z_PQ0XAcxihzHRCES-hU,63
|
|
2
|
-
pulumi_django_azure/django_deployment.py,sha256=yvpOUkcHs37Mb2xTD6BqtB21opxTvFLQzRxMHXTK2aY,23410
|
|
3
|
-
pulumi_django_azure-1.0.4.dist-info/LICENSE,sha256=NX2LN3U319Zaac8b7ZgfNOco_nTBbN531X_M_13niSg,1087
|
|
4
|
-
pulumi_django_azure-1.0.4.dist-info/METADATA,sha256=25RH8tZL2LrhBjuYRngUcRArER9TiAorLEaCJulFhLA,7887
|
|
5
|
-
pulumi_django_azure-1.0.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
6
|
-
pulumi_django_azure-1.0.4.dist-info/top_level.txt,sha256=MNPRJhq-_G8EMCHRkjdcb_xrqzOkmKogXUGV7Ysz3g0,20
|
|
7
|
-
pulumi_django_azure-1.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|