Reputation: 31
I'm trying to create a Cloud Run service using the Deployment Manager, as there's no native support for Cloud Run resource type, I created a type provider for the Cloud Run API by providing it's descriptor at https://run.googleapis.com/$discovery/rest?version=v1.
However, when I run this configuration to create the service using the Deployment Manager, I'm getting the error 404 - Requested entity was not found.
This is because when the Deployment Manager tries to perform the create operation, instead of calling the location specific service endpoint (e.g. https://us-central1-run.googleapis.com), it's using the global endpoint (https://run.googleapis.com) returned by the discovery url, and as stated in the API documentation, the global endpoint supports list method only.
To overcome this problem, I created a custom descriptior file and replaced the rootUrl by pointing it to the location specific service endpoint and I was able to create a Cloud Run service with DM.
I don't intend to keep a custom descriptor file because it may become outdated as the API evolves and I'd like to know if there's another recommended approach to get to correct API url from the Google's official API discovery document.
The following is my DM config:
resources:
- name: cloudrun-type-provider
type: deploymentmanager.v2beta.typeProvider
properties:
descriptorUrl: https://us-central1-run.googleapis.com/$discovery/rest?version=v1
options:
inputMappings:
- fieldName: Authorization
location: HEADER
value: >
$.concat("Bearer ", $.googleOauth2AccessToken())
collectionOverrides:
- collection: namespaces.services
options:
virtualProperties: |
schema: http://json-schema.org/draft-04/schema#
type: object
properties:
metadata:
type: object
description: https://cloud.google.com/run/docs/reference/rest/v1/ObjectMeta
spec:
type: object
description: https://cloud.google.com/run/docs/reference/rest/v1/namespaces.services#ServiceSpec
status:
type: object
description: https://cloud.google.com/run/docs/reference/rest/v1/namespaces.services#ServiceStatus
inputMappings:
- methodMatch: ^create$
location: PATH
fieldName: parent
value: $.concat("namespaces/", $.project)
- methodMatch: ^(get|replaceService|delete)$
location: PATH
fieldName: name
value: $.concat("namespaces/", $.project, "/services/", $.resource.name)
- methodMatch: ^create$
location: BODY
fieldName: apiVersion
value: $.concat("serving.knative.dev/v1")
- methodMatch: ^create$
location: BODY
fieldName: kind
value: $.concat("Service")
- methodMatch: ^create$
location: BODY
fieldName: metadata.name
value: $.resource.name
- methodMatch: ^replaceService$
location: BODY
fieldName: metadata
value: $.resource.self.metadata
- methodMatch: ^(create|replaceService)$
location: BODY
fieldName: spec.template.spec
value: $.resource.properties.spec
- name: dm-cloud-run
type: MY-PROJECT/cloudrun-type-provider:namespaces.services
metadata:
dependsOn:
- cloudrun-type-provider
properties:
spec:
containerConcurrency: 50
timeoutSeconds: 300
containers:
- image: marketplace.gcr.io/google/nginx1
env:
- name: ENV_VAR_1
value: VALUE_1
- name: ENV_VAR_1
value: VALUE_2
resources:
limits:
memory: 512Mi
Upvotes: 3
Views: 424
Reputation: 308
I've managed to get a version of this working after hitting the same issues as you did.
My solution:
gcloud beta deployment-manager --project $PROJECT_ID type-providers create cloudrun --api-options-file=$DIR/../deployment/options.yaml --descriptor-url="https://run.googleapis.com/\$discovery/rest?version=v1"
options.yaml:
options:
inputMappings:
- fieldName: Authorization
location: HEADER
value: >
$.concat("Bearer ", $.googleOauth2AccessToken())
"""Creates the Cloud Run endpoint."""
def GenerateConfig(context):
name: str = context.env['name']
project = context.env['project']
region = context.properties['region']
resources = [{
'name': name,
'type': context.env['project'] + '/cloudrun:run.projects.locations.services.create',
'properties': {
'parent': 'projects/{}/locations/{}'.format(project, region),
'apiVersion': 'serving.knative.dev/v1',
'kind': 'Service',
'metadata': {
'name': '{}-blah'.format(name), # TODO rename
'namespace': 'YOUR_PROJECT_NAME_HERE', # TODO change to your value
},
'spec': {
'template': {
'spec': {
'containerConcurrency': 80,
'timeoutSeconds': 300,
'serviceAccountName': 'YOUR_SERVICE_ACCOUNT_HERE', # TODO change to your value
'containers': [{'image': 'eu.gcr.io/YOUR_PROJECT_HERE/YOUR_IMAGE_HERE'}], # TODO change to your value
},
},
'traffic': [
{'percent': 100, 'latestRevision': True}
],
},
}
}]
return {'resources': resources}
Using type: context.env['project'] + '/cloudrun:run.namespaces.services.create'
(and parent: namespaces/{namespace}
) did not work for me, I also hit that 404. Please note this approach is how the docs describe how to use fully managed.
Instead use type: context.env['project'] + '/cloudrun:run.projects.locations.services.create'
as show in the example snippet. The parent and a few fields will also have to change. A bit of trial and error got me to the final result.
https://run.googleapis.com//$discovery/rest?version=v1
This appears incomplete or inaccurate, trial and error and relying on the response errors to determine exactly what was required and what was not.
Upvotes: 0