[app-engine] multiple app.yaml files

874 views
Skip to first unread message

Raunak Gupta

unread,
Apr 10, 2018, 11:45:37 AM4/10/18
to Google App Engine
I've multiple services running for the same app under the name "dev",  "stage" and "default" (which is prod). 

The deployment is done using the standard `gcloud app deploy app.yaml`.

It is frustrating having to update app.yaml with service name before each deployment. I tried overcoming this by creating multiple app.yaml file for each environment. As an example, for dev, the `app.yaml` file would be stored under ./config/dev/app.yaml'. But now when I deploy using `gcloud app deploy ./config/dev/app.yaml`, gcloud only uploads what is in the /config/dev directory (and nothing from home directory). 

Is there a way to change this behaviour, or an alternative way to manage multiple environments better?

Thanks! 

George (Cloud Platform Support)

unread,
Apr 10, 2018, 2:21:35 PM4/10/18
to Google App Engine
The app.yaml file must be located in your application's root directory. You may check this detail and general app.yaml-related information on the "Configuring your App with app.yaml" documentation page. This means that the ./config/dev/ directory, where app.yaml is saved, must be regarded as the root directory: you should copy all your app's other directories and files accordingly, to dev, from your home directory, or where stored initially. Once this file copy succeeds, and your app directories are placed under the root "dev" directory, the "gcloud app deploy ./config/dev/app.yaml" command should succeed, as expected. 

Depending what your services entail, you might use the "service: service_name" settings in app.yaml. 

Jason Yoon

unread,
Apr 10, 2018, 6:02:18 PM4/10/18
to Google App Engine
"The app.yaml file must be located in your application's root directory. You may check this detail and general app.yaml-related information on the "Configuring your App with app.yaml" documentation page. This means that the ./config/dev/ directory, where app.yaml is saved, must be regarded as the root directory: you should copy all your app's other directories and files accordingly, to dev, from your home directory, or where stored initially. Once this file copy succeeds, and your app directories are placed under the root "dev" directory, the "gcloud app deploy ./config/dev/app.yaml" command should succeed, as expected."

Or alternatively you could have multiple "app.yaml" files in the root directory, and just change the name of each file as well as provide the service flag. For example, app.yaml can be the default service, dev.yaml can be the dev service, and stage.yaml can be the stage service (the name of the file doesn't have to be "app"). Then you can just do `gcloud app deploy app.yaml` or `gcloud app deploy dev.yaml`, etc.

The parameters of `gcloud app deploy` is actually an array of "deployables", meaning you can update multiple services at the same time. So if you wanted to update all environments, you can do `gcloud app deploy dev.yaml stage.yaml app.yaml` if you wanted.

Attila-Mihaly Balazs

unread,
Apr 11, 2018, 3:24:15 AM4/11/18
to Google App Engine
In addition to wat Jason said, you might also want to take at the "includes" directive to avoid repeating yourself: https://cloud.google.com/appengine/docs/standard/python/config/appref

So you could do something like:

- have a common "services.yaml" somewhere
- in each of the dev / stage / prod yaml just put the information specific for that env and include the common services yaml

Sidenote: we have a small helper script for our GAE projects so that we can do some more processing around running / deploying and we generate our app.yaml's dynamically:

def _buildAppYamls(for_deployment):
    app_yaml_templates = _findInAppengineModules('app-template.yaml')
    for template in app_yaml_templates:
        content = _load(template)
        d = os.path.dirname(template)
        module = os.path.basename(d)
        if module != 'main':
            module_tag = 'service' if for_deployment else 'module'
            content = '%s: %s\n%s' % (module_tag, module, content)
        if not for_production:
            content = 'version: local-development\n' + content
        with open(os.path.join(d, 'app.yaml'), 'w') as f:
            f.write(content)
Reply all
Reply to author
Forward
0 new messages