Deployment Manager is an infrastructure deployment service that automates the creation and management of Google Cloud Platform resources. A lot of GCP resources can be created using the available GDM types. In essence a GDM type is an abstraction on top of the API of a GCP service. However some types are missing, so in this blog I want to show you how to add those yourself. GDM supports jinja2 and Python templates, for this blog we will use python.
Finding the discovery document
Before we can create our new type we need to find the discovery document associated with the API of the service we want to add. The information provided by the discovery document includes API-level properties such as an API content, resource schemas, authentication scopes, and methods. A link to the document is located in the rest documentation of the service, for example: https://cloud.google.com/scheduler/docs/reference/rest
Creating the type provider
Since we now have the discovery document, we can create our type resource. It’s important to add the “inputMappings” property, because this holds the credentials needed to authenticate with the API.
def _generateSchedulerTypeResource(context):
properties = {
'descriptorUrl': 'https://cloudscheduler.googleapis.com/$discovery/rest?version=v1beta1',
'options': {
'inputMappings': [
{
'fieldName': 'Authorization',
'location': 'HEADER',
'value': '$.concat("Bearer ", $.googleOauth2AccessToken())',
},
],
}
}
return {
‘name‘: ‘cloudscheduler-v1beta1‘,
‘type‘: ‘deploymentmanager.v2beta.typeProvider‘,
‘properties‘: properties,
}
Creating the resource
Using our freshly created type provider we can define a service resource. The “action” property in the code below is a concatenation of the project id, type provider name and rest api endpoint id, which can be distilled from the discovery document.
The “properties” dict holds the request properties you want to send to the API. The value of the “dependsOn” property must correspond with the name of the type provider.
def _generateSchedulerJobResource(context):
project_id = 'myprojectid'
region = 'europe-west2'
parent = 'projects/' + project_id + '/locations/' + region
name_short = 'myjob'
name_full = parent + '/jobs/' + name_short
topic = 'trigger-job'
properties = {
‘name‘: name_full,
‘parent‘: parent,
‘content‘: name_short,
‘schedule‘: ‘0 6 */1 * *‘,
‘timeZone‘: ‘Europe/Brussels‘,
‘pubsubTarget‘: {
‘topicName‘: ‘projects/‘ + project_id + ‘/topics/‘ + topic,
‘attributes‘: {
‘source‘: ‘cloudscheduler‘,
},
},
}
metadata = {
‘dependsOn‘: [‘cloudscheduler-v1beta1‘],
}
return {
‘name‘: ‘cloudscheduler-job-‘ + name_short,
‘action‘: project_id + ‘/cloudscheduler-v1beta1:cloudscheduler.projects.locations.jobs.create‘,
‘properties‘: properties,
‘metadata‘: metadata,
}
Putting it together
In our main function, which needs to be called “GenerateConfig”, we define a list holding the resources we want to create.
def GenerateConfig(context):
resources = [
_generateSchedulerTypeResource(context),
_generateSchedulerJobResource(context),
]
return {‘resources‘: resources}