TAP on AKS (1.0.0) : Part 3 – Deploy an application with testing in ACR repo

Reading Time: 4 mins

Overview

In this section, I will walk you through the steps required to deploy an application using the Tanzu Application Platform. Before moving further, please ensure below are completed:

  • Prepare set up is completed, If not done, then follow the steps in the post
  • Default kubeconfig context is set to the target Kubernetes cluster.
  • Tanzu Application Platform GUI is successfully installed, for more details, read here

Install Supply Chain with Testing

This Cartographer Supply Chain ties a series of Kubernetes resources which, when working together, drives a developer-provided Workload from source code all the way to a Kubernetes configuration ready to be deployed to a cluster, passing forward the source code to image building if and only if the testing pipeline supplied by the developers run successfully. It includes below capabilities:

  • Watching a Git Repository or local directory for changes
  • Running tests from a developer-provided Tekton or Pipeline
  • Building a container image out of the source code with Buildpacks
  • Applying operator-defined conventions to the container definition
  • Deploying the application to the same cluster

You can verify that you have the right set of supply chains installed by running the following command:

tanzu apps cluster-supply-chain list
NAME READY AGE LABEL SELECTOR
source-test-to-url Ready 5h38m apps.tanzu.vmware.com/has-tests=true,apps.tanzu.vmware.com/workload-type=web

Setup Developer Namespaces to use Installed Packages

To create workload for your application using the registry credentials specified, run these commands to add credentials and Role-Based Access Control (RBAC) rules to the namespace that you plan to create the workload in:

# Syntax: 

kubectl create secret docker-registry registry-credentials --docker-server=REGISTRY-SERVER --docker-username=REGISTRY-USERNAME --docker-password=REGISTRY-PASSWORD -n YOUR-NAMESPACE

# Example: where --docker-server, --docker-username and --docker-password are the details collected earlier after creating ACR repo.

kubectl create secret docker-registry image-secret --docker-server=captainrepo.azurecr.io --docker-username=captainrepo --docker-password=hGQ9Xqm111111111111Bd3o -n tap-install
  • Add placeholder read secrets, a service account, and RBAC rules to the developer namespace by running:
cat <<EOF | kubectl -n tap-install apply -f -

apiVersion: v1
kind: Secret
metadata:
name: tap-registry
annotations:
secretgen.carvel.dev/image-pull-secret: ""
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: e30K

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
secrets:
- name: registry-credentials
imagePullSecrets:
- name: registry-credentials
- name: tap-registry

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: default
rules:
- apiGroups: [source.toolkit.fluxcd.io]
resources: [gitrepositories]
verbs: ['*']
- apiGroups: [source.apps.tanzu.vmware.com]
resources: [imagerepositories]
verbs: ['*']
- apiGroups: [carto.run]
resources: [deliverables, runnables]
verbs: ['*']
- apiGroups: [kpack.io]
resources: [images]
verbs: ['*']
- apiGroups: [conventions.apps.tanzu.vmware.com]
resources: [podintents]
verbs: ['*']
- apiGroups: [""]
resources: ['configmaps']
verbs: ['*']
- apiGroups: [""]
resources: ['pods']
verbs: ['list']
- apiGroups: [tekton.dev]
resources: [taskruns, pipelineruns]
verbs: ['*']
- apiGroups: [tekton.dev]
resources: [pipelines]
verbs: ['list']
- apiGroups: [kappctrl.k14s.io]
resources: [apps]
verbs: ['*']
- apiGroups: [serving.knative.dev]
resources: ['services']
verbs: ['*']
- apiGroups: [servicebinding.io]
resources: ['servicebindings']
verbs: ['*']
- apiGroups: [services.apps.tanzu.vmware.com]
resources: ['resourceclaims']
verbs: ['*']
- apiGroups: [scanning.apps.tanzu.vmware.com]
resources: ['imagescans', 'sourcescans']
verbs: ['*']

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: default
subjects:
- kind: ServiceAccount
name: default

EOF

Tekton pipeline

A pipeline to be ran whenever the supply chain hits the stage of testing the source code. Save below into a yaml file for ex:  tekton-pipeline.yaml

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: developer-defined-tekton-pipeline
labels:
apps.tanzu.vmware.com/pipeline: test # (!) required
spec:
params:
- name: source-url # (!) required
- name: source-revision # (!) required
tasks:
- name: test
params:
- name: source-url
value: $(params.source-url)
- name: source-revision
value: $(params.source-revision)
taskSpec:
params:
- name: source-url
- name: source-revision
steps:
- name: test
image: gradle
script: |-
cd `mktemp -d`
wget -qO- $(params.source-url) | tar xvz
./mvnw test

Run the yaml file with following command in tap-install namespace:

kubectl apply -f tekton-pipeline.yaml -n tap-install
pipeline.tekton.dev/developer-defined-tekton-pipeline created

Image Secret:

Regardless of the supply chain that a Workload goes through, there must be a secret in the developer namespace. This secret contains the credentials to be passed to

# Example:  where --docker-server, --docker-username and --docker-password are the details collected earlier after creating ACR repo. 

kubectl create secret docker-registry image-secret --docker-server=captainrepo.azurecr.io --docker-username=captainrepo --docker-password=hGQ9Xqm111111111111Bd3o -n tap-install

Deploy Application

To deploy your application, you must download an accelerator, upload it on your Git repository of choice, and run a CLI command. Let me take you through the steps of downloading an accelerator through TAP-GUI:

  • From the Tanzu Application Platform GUI portal, click on Accelerators on the left side of the navigation bar to see the list of available accelerators.
  • Locate the Tanzu Java Web App accelerator, which is a sample Spring Boot web app, and click on Choose button.

  • In the Generate Accelerators prompt, replace the default value dev.local in the prefix for container image registry field with the registry in the form of SERVER-NAME/REPO-NAME. The SERVER-NAME/REPO-NAME must match what was specified for registry as part of the installation values for ootb_supply_chain_basic. Click NEXT STEP, verify the provided information, and click CREATE.

  • After the Task Activity processes are complete, click on the DOWNLOAD ZIP FILE button

  • After downloading the zip file, expand it in a workspace directory and follow your preferred procedure for uploading the generated project files to a Git repository for your new project.
# Unzip the downloaded file and follow below process to push to git repo: 

reddye@reddye-a02 tanzu-java-web-app-demo % ls
LICENSE Tiltfile catalog-info.yaml mvnw pom.xml
README.md accelerator-log.md config mvnw.cmd src

# Initialize git

reddye@reddye-a02 tanzu-java-web-app-demo % git init

Initialized empty Git repository in /Users/reddye/Downloads/tanzu-java-web-app-demo/.git/

#Add all the files
git add *

#Commit
git commit -am "First commit"

git branch -M main

# Created a new repo named tanzu-java-web-app-demo in my github account and later executed below command:

git remote add origin https://github.com/Eknathreddy09/tanzu-java-web-app-demo.git

# Syntax: git config --global user.email "github account email"

git config --global user.email "[email protected]"

$ git push -u origin main
Username for 'https://github.com': eknathreddy09
Password for 'https://[email protected]':
Enumerating objects: 28, done.
Counting objects: 100% (28/28), done.
Delta compression using up to 16 threads
Compressing objects: 100% (19/19), done.
Writing objects: 100% (28/28), 15.36 KiB | 3.07 MiB/s, done.
Total 28 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/Eknathreddy09/tanzu-java-web-app-demo.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

# Login to Github account and verify the repo.

For this demo, instead of downloading from accelerator, I have a used a public version to test which is available here

  • Deploy the Tanzu Java Web App accelerator by running the tanzu apps workload create command:
$  tanzu apps workload create tanzu-java-web-app  --git-repo https://github.com/Eknathreddy09/tanzu-java-web-app --git-branch main --type web --label apps.tanzu.vmware.com/has-tests=true --label app.kubernetes.io/part-of=tanzu-java-web-app  --type web -n tap-install --yes

# View the build and runtime logs for your app by running the tail command:

tanzu apps workload tail tanzu-java-web-app --since 10m --timestamp -n tap-install

# Get the status of application:

tanzu apps workload get tanzu-java-web-app -n tap-install
# tanzu-java-web-app: Ready
---
lastTransitionTime: "2022-01-20T09:05:51Z"
message: ""
reason: Ready
status: "True"
type: Ready

Workload pods
NAME STATE AGE
tanzu-java-web-app-00001-deployment-57d5d9695c-gdrrj Running 6s
tanzu-java-web-app-build-1-build-pod Succeeded 3h11m
tanzu-java-web-app-config-writer-wxc9k-pod Succeeded 3h6m
tanzu-java-web-app-mzbst-test-pod Succeeded 3h18m

Workload Knative Services
NAME READY URL
tanzu-java-web-app Ready http://tanzu-java-web-app.tap-install.example.com
Workload Knative Services
NAME READY URL
tanzu-java-web-app Ready http://tanzu-java-web-app.tap-install.example.com
  • Collect the External IP of Envoy service in name space: tanzu-system-ingress
kubectl get svc envoy -n tanzu-system-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
envoy LoadBalancer 10.0.253.99 20.207.73.193 80:30870/TCP,443:31178/TCP 5h51m
  • Add an entry in your local machine /etc/hosts with the IP collected above pointing to hostname: tanzu-java-web-app.tap-install.example.com

  • Access the url tanzu-java-web-app.tap-install.example.com and you should see result as below:

Verify the test results:

kubectl get pods -n tap-install
NAME READY STATUS RESTARTS AGE
tanzu-java-web-app-build-1-build-pod 0/1 Completed 0 65m
tanzu-java-web-app-config-writer-wxc9k-pod 0/1 Completed 0 60m
tanzu-java-web-app-mzbst-test-pod 0/1 Completed 0 72m
kubectl logs tanzu-java-web-app-mzbst-test-pod -n tap-install
taskExecutorBuilder
themeResolver
viewControllerHandlerMapping
viewNameTranslator
viewResolver
welcomePageHandlerMapping
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.207 s - in com.example.springboot.HelloControllerTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:23 min
[INFO] Finished at: 2022-01-20T09:01:01Z
[INFO] ------------------------------------------------------------------------
kubectl get workload,gitrepository,pipelinerun,images.kpack,podintent,app,services.serving -n tap-install
NAME SOURCE SUPPLYCHAIN READY REASON
workload.carto.run/tanzu-java-web-app https://github.com/Eknathreddy09/tanzu-java-web-app source-test-to-url True Ready

NAME URL READY STATUS AGE
gitrepository.source.toolkit.fluxcd.io/tanzu-java-web-app https://github.com/Eknathreddy09/tanzu-java-web-app True Fetched revision: main/90bd107ad26e228886e2ad28c964580858196376 70m

NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
pipelinerun.tekton.dev/tanzu-java-web-app-mzbst True Succeeded 70m 63m

NAME LATESTIMAGE READY
image.kpack.io/tanzu-java-web-app captainrepo.azurecr.io/supply-chain/tanzu-java-web-app-tap-install@sha256:5b4d8b4652a13a8a15966f5ef5a2a5c3dd892dc909b5355f3703dba5e3e601d8 True

NAME READY REASON AGE
podintent.conventions.apps.tanzu.vmware.com/tanzu-java-web-app True 59m

NAME DESCRIPTION SINCE-DEPLOY AGE
app.kappctrl.k14s.io/accelerator Reconcile succeeded 3m59s 3h38m
app.kappctrl.k14s.io/api-portal Reconcile succeeded 3m35s 3h49m
app.kappctrl.k14s.io/appliveview Reconcile succeeded 3m46s 3h39m
app.kappctrl.k14s.io/appliveview-conventions Reconcile succeeded 3m18s 3h39m
app.kappctrl.k14s.io/buildservice Reconcile succeeded 3m31s 3h49m
app.kappctrl.k14s.io/cartographer Reconcile succeeded 3m36s 3h43m
app.kappctrl.k14s.io/cert-manager Reconcile succeeded 67s 3h49m
app.kappctrl.k14s.io/cnrs Reconcile succeeded 2m43s 3h38m
app.kappctrl.k14s.io/contour Reconcile succeeded 2m16s 3h43m
app.kappctrl.k14s.io/conventions-controller Reconcile succeeded 3m15s 3h43m
app.kappctrl.k14s.io/developer-conventions Reconcile succeeded 3m38s 3h39m
app.kappctrl.k14s.io/fluxcd-source-controller Reconcile succeeded 3m24s 3h49m
app.kappctrl.k14s.io/grype Reconcile succeeded 4m3s 3h42m
app.kappctrl.k14s.io/image-policy-webhook Reconcile succeeded 3m21s 3h43m
app.kappctrl.k14s.io/learningcenter Reconcile succeeded 3m34s 3h38m
app.kappctrl.k14s.io/learningcenter-workshops Reconcile succeeded 3m46s 3h27m
app.kappctrl.k14s.io/metadata-store Reconcile succeeded 3m41s 3h43m
app.kappctrl.k14s.io/ootb-delivery-basic Reconcile succeeded 7m25s 3h39m
app.kappctrl.k14s.io/ootb-supply-chain-testing Reconcile succeeded 6m36s 3h39m
app.kappctrl.k14s.io/ootb-templates Reconcile succeeded 4m11s 3h40m
app.kappctrl.k14s.io/scanning Reconcile succeeded 3m20s 3h49m
app.kappctrl.k14s.io/service-bindings Reconcile succeeded 3m58s 3h49m
app.kappctrl.k14s.io/services-toolkit Reconcile succeeded 3m15s 3h49m
app.kappctrl.k14s.io/source-controller Reconcile succeeded 3m38s 3h49m
app.kappctrl.k14s.io/spring-boot-conventions Reconcile succeeded 4m4s 3h39m
app.kappctrl.k14s.io/tanzu-java-web-app Reconciling 3s 57m
app.kappctrl.k14s.io/tap Reconcile succeeded 5m58s 3h49m
app.kappctrl.k14s.io/tap-gui Reconcile succeeded 3m58s 3h38m
app.kappctrl.k14s.io/tap-telemetry Reconcile succeeded 3m37s 3h49m
app.kappctrl.k14s.io/tekton-pipelines Reconcile succeeded 3m27s 3h49m

NAME URL LATESTCREATED LATESTREADY READY REASON
service.serving.knative.dev/tanzu-java-web-app http://tanzu-java-web-app.tap-install.example.com tanzu-java-web-app-00001 tanzu-java-web-app-00001 True