Skip to content

Commit 4ef7d6c

Browse files
author
Vivek Lakshmanan
committed
Add python SDK call example
1 parent 858d4fe commit 4ef7d6c

File tree

8 files changed

+118
-164
lines changed

8 files changed

+118
-164
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ Example | Description |
177177
[Azure Kubernetes Service](azure-py-aks) | Create an Azure Kubernetes Service (AKS) Cluster.
178178
[Azure App Service](azure-py-appservice) | Build a web application hosted in App Service and provision Azure SQL Database and Azure Application Insights.
179179
[Azure App Service with Docker](azure-py-appservice-docker) | Build a web application hosted in App Service from Docker images.
180+
[Azure SDK integration](azure-py-call-azure-sdk) | Call Azure SDK functions from a Pulumi program in Python.
180181
[Azure Cosmos DB and LogicApp](azure-py-cosmosdb-logicapp) | Define Cosmos DB, API connections, and link them to a logic app.
181182
[Minecraft Server](azure-py-minecraft-server) | Deploy an Azure Virtual Machine and provision a Minecraft server.
182183
[Static Website](azure-py-static-website) | Configure static website hosting in Azure Storage.
@@ -192,6 +193,7 @@ Example | Description |
192193
[Azure Kubernetes Service](azure-go-aks) | Create an Azure Kubernetes Service (AKS) Cluster.
193194
[Azure App Service with Docker](azure-go-appservice-docker) | Build a web application hosted in App Service from Docker images.
194195
[Static Website](azure-go-static-website) | Configure static website hosting in Azure Storage.
196+
[Azure SDK integration](azure-go-call-azure-sdk) | Call Azure SDK functions from a Pulumi programin Go.
195197

196198
### C#
197199

@@ -388,4 +390,4 @@ Example | Description |
388390

389391
## Automation API
390392

391-
[Automation API Examples](https://github.com/pulumi/automation-api-examples)
393+
[Automation API Examples](https://github.com/pulumi/automation-api-examples)

azure-py-call-azure-sdk/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.pyc
2+
venv/

azure-py-call-azure-sdk/Pulumi.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: azure-py-call-azure-sdk
2+
runtime:
3+
name: python
4+
options:
5+
virtualenv: venv
6+
description: An example of integrating an Azure SDK call to a Pulumi program.

azure-py-call-azure-sdk/README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new)
2+
3+
# Demo of Integrating the native Azure Pulumi provider with the Microsoft Azure SDK
4+
5+
The native Azure Pulumi provider exposes the entire resource model of Azure Resource Manager. Each resource can be created, updated, deleted, or refreshed (read).
6+
7+
However, Azure API has many endpoints that don't map to our resource model. For examples, finding resources given some filter criteria is not supported directly.
8+
9+
However, you can easily integrate an Azure SDK call inside your Pulumi program using the same programming language. We provide a helper function `authorization.get_client_token()` that returns a valid authentication token for the same login context that the Pulumi provider is using.
10+
11+
This example demonstrates how to use such integration to lookup a role definition ID based on its name and scope. It then creates a role assignment for the resulting definition to allow pulling container images from a registry.
12+
13+
## Running the App
14+
15+
1. Create a new stack:
16+
17+
```
18+
$ pulumi stack init dev
19+
```
20+
21+
1. Login to Azure CLI (you will be prompted to do this during deployment if you forget this step):
22+
23+
```
24+
$ az login
25+
```
26+
27+
1. Set the Azure region location to use:
28+
29+
```
30+
$ pulumi config set azure-native:location WestUS
31+
```
32+
33+
1. Run `pulumi up` to preview and deploy changes:
34+
35+
```
36+
$ pulumi up
37+
Previewing changes:
38+
...
39+
Performing changes:
40+
...
41+
Resources:
42+
+ 4 created
43+
```

azure-py-call-azure-sdk/__main__.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""A program to demonstrate accessing Azure Python SDK"""
2+
3+
from azure.core.credentials import AccessToken
4+
from azure.mgmt.authorization import AuthorizationManagementClient
5+
from pulumi_azure_native import authorization, containerregistry, resources
6+
7+
8+
class TokenCred:
9+
def __init__(self, token):
10+
self.token = token
11+
12+
def get_token(self, *scopes, **kwargs) -> 'AccessToken':
13+
return AccessToken(token=self.token, expires_on=-1)
14+
15+
16+
def get_role_id_by_name(name, scope=""):
17+
config = authorization.get_client_config()
18+
client_token = authorization.get_client_token()
19+
client = AuthorizationManagementClient(
20+
TokenCred(client_token.token), config.subscription_id)
21+
def_pages = client.role_definitions.list(
22+
scope, filter=f'roleName eq {name}')
23+
role = None
24+
for x in def_pages:
25+
role = x.id
26+
break
27+
if role is None:
28+
raise Exception(f'role \'{name}\' not found at scope \'{scope}\'')
29+
return role
30+
31+
32+
# Create an Azure Resource Group
33+
resource_group = resources.ResourceGroup('resource_group')
34+
35+
# Create a container registry
36+
container_registry = containerregistry.Registry(
37+
'registry',
38+
resource_group_name=resource_group.name,
39+
sku=containerregistry.SkuArgs(name='Basic'),
40+
admin_user_enabled=True)
41+
42+
client_config = authorization.get_client_config()
43+
current_principal = client_config.object_id
44+
45+
roledef = get_role_id_by_name('AcrPull')
46+
47+
authorization.RoleAssignment("access-from-cluster",
48+
principal_id=current_principal,
49+
# adjust this if running as service principal
50+
principal_type=authorization.PrincipalType.USER,
51+
role_definition_id=roledef,
52+
scope=container_registry.id)
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pulumi>=3.0.0,<4.0.0
2+
pulumi-azure-native>=1.0.0,<2.0.0
3+
azure-mgmt-authorization>=1.0.0

misc/test/azure_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,15 @@ func TestAccAzurePyWebserver(t *testing.T) {
166166
integration.ProgramTest(t, &test)
167167
}
168168

169+
func TestAccAzurePyCallAzureSdk(t *testing.T) {
170+
test := getAzureBase(t).
171+
With(integration.ProgramTestOptions{
172+
Dir: path.Join(getCwd(t), "..", "..", "azure-py-call-azure-sdk"),
173+
})
174+
175+
integration.ProgramTest(t, &test)
176+
}
177+
169178
func TestAccAzureTsAppService(t *testing.T) {
170179
test := getAzureBase(t).
171180
With(integration.ProgramTestOptions{

0 commit comments

Comments
 (0)