Skip to content

Latest commit

 

History

History
 
 

app-factory-template

Overview

The Application Factory is an example of a golden path, that allows teams to quickly provision application landing zones in the multi-tenant infrstructure and single-tenant infrastructure in a self-service manner. Using the Application Factory developers, devops engineers or platform admins can create code repositories, an application landing zone, application CI/CD pipeline and an infrastructure as code pipeline to manage infrastructure dedicated to the application. The landing zone and infrastructure is created using Terraform and yaml templates defined by platform administrators so best practices are adopted from day 1.

The app-factory-template directory contains the structure and Cloud Build triggers that teams will use to create new applications and manage application teams in the software delivery platform. app-factory-template folder is hydrated into a repository during the execution of the software-delivery-app.sh script.

Table of Contents

Application Factory Architecture

app-factory-architecture

The diagram above shows the components of the Application Factory and their interactions:

  1. Users start the process of creating a new application by providing the application name and runtime to the create-app Cloud Buildcloud-build trigger.
  2. Cloud Build performs variable substitution in application.tf.tpl to hydrate Terraform to represent the new application. The hydrated Terraform is committed in the Application Factory's git repository as <application_name>.tf.
  3. The tf-apply Cloud Build trigger reads the new code and starts the process of deploying new resources.
  4. Applying the Terraform creates new git repos for the application code and application's infrastructure as code off of the runtime's template and infra-template respectively. Terraform also hydrates the Kubernetes landing zone in the Anthos Config Management repo. Finally this process also creates the application's CI/CD project and infrastructure as code Cloud Build trigger.
  5. The application's infrastructure as code Cloud Build trigger creates the CI/CD pipeline for application deployments.
  6. Anthos Config Management deploys the landing zone to the multi-tenant GKE clusters that includes a namespace, network policy and workload identity.
  7. The application's CI/CD pipeline performs the initial deployment of the application to the GKE clusters.
  8. Optionally, the application team use the infrastructure as code Cloud Build trigger to deploy projects and additional resources (CloudSQL, Pub/Sub, etc.) to dedicated projects. As a best practice Terraform modules should be provided to application teams for those resources so best practices are automatically applied.

Templates

templates folder contains the templates that are used to populate the apps and teams folders. When their respective pipelines are run those template are hydrated with the values provided by the application team and platform team.

The templates for applications and teams is intentionally very small and uses the modules defined in terraform-modules for the majority of the logic.

Application Template

The application template (application.tf.tpl) is the IaC used to create the following resources.

  • Application CI/CD project
  • Secrets copied from the multi-tenant admin project
  • Application code repository from the language specific template
  • Application group IaC repository from the infra-template
  • Infrastructure as code Cloud Build trigger in the CI/CD project

Team Template

The team template (team.tf.tpl) is a Terraform snippet that is invoked to manage team structures in GitHub. The Cloud Build trigger add-team-files and template enables application teams to self-manage who has access to their respositories. Managing teams as IaC makes it easier for security teams to audit who has access to different respositories.

Scripts

The shell scripts under setup folder are used to hydrate the templates into actual Terraform files from the templates.

Apps

apps will contain the actual hydrated Terraform used to create and manage the applications provisioned on the software delivery platform. The hydrated Terraform is created via the create-app Cloud Build trigger in the application factory project.

Defining the applications as Terraform has a number of benefits in the operation of the platform:

  1. There is a central location to see what applications have been provisioned.
  2. The infrastructure as code approach brings consistency to the management process.
  3. Updates to the applcation bases can be broadly applied with little effort by platform administrators.

Once the blueprint is deployed and applications have been provisioned the folder structure will look similar to:

 -  apps
 |--  golang
 |----  application1.tf
 |----  application2.tf
 |--  java
 |----  application3.tf

Teams

teams will contain the hyrdated Terraform used to create and manage your teams in GitHub. The hydrated Terraform is created via the add-team-files Cloud Build trigger in the application factory project.

By default in teams there are two sample templates engineering.tpl and devops.tpl provided. The templates basical specify who will be the members of the team, which repos will the team have access to and any parent/child relationship of teams (nested teams).

The folder structure under teams will reflect the nested structure as you specify in the templates of the teams. For example, if you create a team Engineering and then a child team DevOps the folder structure will look similar to:

 -  teams
 |--  engineering
 |----  devops

Config

The config folder contains configurations files used by the add-team-files and create-app triggers:

  • app_runtimes_list.txt is an allow list of type of application runtimes that are supported by Application factory.
  • The files in team-configs are the GitHhub teams that you create.

Cloud Build Triggers

The application factory has four Cloud Build tiggers, each are defined as yaml files in the app-factory-template.

  1. create-app, this trigger hydrates an application template and stores it in apps folder.
  2. add-team-files, this trigger processes the teams config and stores the resulting Terraform in the teams folder.
  3. tf-plan, performs a Terraform plan.
  4. tf-apply, performs Terraform apply, updating the provisioned applications and teams in GitHub.

Note: The script software-delivery-app.sh that creates your application factory accepts an input "TRIGGER_TYPE" which can be either webhook or github. If github is passed as "TRIGGER_TYPE" to the script, the script creates GitHub triggers in Cloud Build. If webhook is passed as "TRIGGER_TYPE" to the script, the script creates webhook triggers in Cloud Build.

The following table shows which configuration file is linked with which trigger in Cloud Build:

Trigger Name If it is a webhook trigger If it is a webhook github trigger
create-app add-app-tf-files-webhook.yaml add-app-tf-files-github-trigger.yaml
add-team-files add-app-tf-files-webhook.yaml add-app-tf-files-github-trigger.yaml
tf-plan tf-plan-webhook.yaml tf-plan-github-trigger.yaml
tf-apply tf-apply-webhook.yaml tf-apply-github-trigger.yaml

Once your application factory has been created, you may delete the configuration files that are no longer required. e.g if you created webhook triggers in Cloud Build, you can delete the configuration files for github triggers or vice-versa. This is not a mandatory step but is recommended to avoid any confusion.

Application Factory workflows

The next sections will outline common workflows in the software delivery platform and how to perform them in blueprint.

Create a new Application

  • Run the trigger create-app in the Application factory. You will need to pass the following parameters:
    • Application name
    • Runtime language
  • Run the tf-plan trigger to verify the actions Terraform will take.
  • Run the tf-apply trigger, which will create the new application on the platform.

The trigger will generate the Terraform code to spin up a new application and save it in a .tf file with the same name as the application under the runtime language folder. For example, if you run create-app trigger to create an application with name as booking and golang as the runtime language, the trigger will create a file named booking.tf under apps/golang folder.

Create a new GitHub team

  • In teams create a new template with the same name as the team you are creating. For example, to create a team called Operations, you will need to create a file named operations.tpl under the config/teams-config folder. Note that the names are case-insensitive.
  • Commit and push your changes to the app-factory repo, as specified when running the software-delivery-app.sh launch script.
  • Run add-team-files trigger in the Application factory. Passing the following parameters:
    • Team name (It should be the same as the name of the file you committed in previous step.)
  • Run the tf-plan trigger to verify the actions Terraform will take.
  • Run the tf-apply trigger, which will create the new team in your GitHub organization.

The trigger will create Terraform code to describing the GitHub team and save it as .tf file under teams folder in this repo.

Delete an application

If you have already deployed the application using a Cloud Deploy pipeline or IaC trigger has run successfully at least once, follow these steps to delete the pipelines first:

  • Delete the delivery pipelines corresponding to the application:
    • gcloud beta deploy delivery-pipelines delete <pipeline name> --region <region> --force
  • Find the release targets corresponding to the application:
    • gcloud beta deploy targets list --region <region>
  • Delete the release targets corresponding to the application:
    • gcloud beta deploy targets delete <name obtained from the above command> --region <region>

Once the above steps have been completed or if the application has not been deployed by a Cloud Deploy pipeline, follow the following steps.

  • Delete the .tf file for the application under apps/<runtime> folder.
  • Commit and push the change.
  • Run the tf-plan trigger to verify the actions Terraform will take.
  • Run the tf-apply trigger. It will refresh Terraform state and delete the resource related to the application.

Delete a team

  • Edit teams/main.tf to remove the module reference to the team that you want to delete.
  • Delete the folder named after the team from teams directory.
  • Commit and push the changes.
  • Run the tf-plan trigger to verify the actions Terraform will take.
  • Run the tf-apply trigger. It will refresh Terraform state and delete the GitHub team.

Manage an Application

Application components

When you create an application via Application Factory, you get the following components:

  • A GCP project, the Application Admin project. The name of this project will be application-name-tf-admin.
  • Two git repos named application-name and application-name-infra.
    • The application-name repo is the source code repo that is created from a template based on the type of application you have created. For example, if you created a Java application, the application-name source repo will be cloned from app-template-java template repository.
    • The application-name-infra repo will contain the IaC for building infrastructure and CI/CD pipeline for the application. This is created from infra-template template repository.
  • IaC Cloud Build trigger named deploy-infra
    • deploy-infra trigger is connected to application-name-infra repo
    • While creating the application from the Application Factory, you choose TRIGGER_TYPE as either "webhook" or "github" to create deploy-infra as a webhook trigger or a GitHub trigger.

Create CICD pipeline for the application through IaC Cloud Build trigger

  • IaC Cloud Build trigger deploy-infra creates the CI/CD pipeline of the application. You can kick-off deploy-infra trigger by any of the following ways:
    • Do a push to _application-name_infra repo.
    • If the trigger is a GitHub trigger, run the trigger manually from Google Cloud console on cicd-trigger branch.
    • If the trigger is a webhook trigger, make a cURL call with the webhook endpoint. The webhook endpoint can be obtained from Google Cloud Console when you click open the trigger and go to "show url" section.
  • Once the trigger has successfully completed, you will have the following components created in the Application Admin project:
    • A CI/CD Cloud Build trigger named deploy-app that is connected to the application-name repository.
    • An Artifact Registry repo.
    • Cloud Deploy targets for dev, staging and prod GKE clusters that were created as part of multi-tenant infrastructure.

Deploy the application through CICD Cloud Build trigger

  • The deploy-app trigger type (webhook or GitHub) will be the same as deploy-infra, unless you override it in _applicaton_name-infra repo.
  • You can deploy the application by any of the following ways:
    • Do a push to application repo.
    • If the trigger is a GitHub trigger, run the trigger manually from Google Cloud console on main branch.
    • If the trigger is a webhook trigger, make a cURL call with the webhook endpoint. The webhook endpoint can be obtained from Google Cloud Console when you click open the trigger and go to "show url" section.
  • The trigger will take the code from the main branch of application-name repo and perform the following actions:
    • Using Skaffold build a Docker image from source code, storing the Docker image in Artifact Registry.
    • Invoke a Cloud Deploy pipeline that will deploy the artifacts on the targets which were created by IaC Cloud Build trigger, this step also hydrates kustomization files from the application-name repo.

Change Infrastructure for the application

  • All the infrastructure for the application is created from IaC residing in application-name-infra repo.
  • application-name-infra repo follows the branch and folder pattern to represent and manage environments. The repo contains four branches and folders cicd-trigger, dev, staging and prod.
    • Admin project branch (cicd-trigger) : The cicd-trigger branch/folder contains the IaC used to maintain the application's CI/CD pipelines including Artifact Registry repo and Cloud Deploy targets.
    • Environment branches (dev, staging, prod) : The other branches/folders represent environments containing infrastructure dedicated to a single application.
  • Similar to the multi-tenant infrastructure repo you can only push to the default branch i.e cicd-trigger branch for this repo, use pull requests to review and merge changes into the dev, staging and production environments.
  • A push to the repo invokes deploy-infra trigger and apply the changes for the

Change Application code

  • application-name is the repo that contains the source code.
  • Change the code and commit it. When the commit is pushed to the repo, the deploy-app trigger is invoked automatically and deploys the latest code to the required target.

Change IaC Cloud Build trigger pipeline

  • IaC Cloud Build trigger deploy-infra is connected to the application-name-infra repo.
  • If the trigger was created as a GitHub trigger, the cloudbuild.yaml in application-name-infra repo will be used as configuration file(execution steps) for the trigger. You can change the yaml file if you need to change the trigger's execution steps.
  • If the trigger was created as a webhook trigger, the configuration of the trigger will be inline in the Cloud Build trigger. In this scenario you will not need cloudbuild.yaml in application-name-infra repo so it is recommended to delete it to avoid confusion. To change the deploy-infra trigger's execution steps, it is recommended to create a new version of Terraform module that creates the trigger in the Application Factory. Alternatively, you can change it inline by opening the trigger from Google Cloud console or Google Cloud CLI or SDK, not recommended since those update could be overwritten by the Application Factory's next run.

Change CICD Cloud Build trigger pipeline

  • CI/CD Cloud Build trigger deploy-app is connected to the application-name repo.
  • If the trigger was created as a GitHub trigger, the cloudbuild.yaml in application-name repo will be used as configuration file(execution steps) for the trigger. You can change the yaml file if you need to change the trigger's execution steps.
  • If the trigger was created as a webhook trigger, the configuration of the trigger will be inline in the Cloud Build trigger. In this scenario you will not need cloudbuild.yaml in application-name-infra repo so it is recommended to delete it to avoid confusion. To change the deploy-app trigger's execution steps, it is recommended to create a new version of Terraform module that creates the trigger in IaC Cloud Build pipeline. Alternatively, you can change it inline by opening the trigger from Google Cloud console or Google Cloud CLI or SDK, not recommended since those update could be overwritten by the Iac pipeline.

Usage

Copyright 2022 Google. This software is shared as sample code and not intended for production use and provided as-is, without warranty or representation for any use or purpose. Your use of it is discretionary and subject to your agreement with Google.