You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
8.2 KiB

  1. #!/usr/bin/env bash
  2. # http://redsymbol.net/articles/unofficial-bash-strict-mode
  3. set -euo pipefail
  4. usage()
  5. {
  6. cat <<END
  7. deploy.sh: deploys the $app_name application to a Kubernetes cluster using Helm.
  8. Parameters:
  9. --aks-name <AKS cluster name>
  10. The name of the AKS cluster. Required when the registry (using the -r parameter) is set to "aks".
  11. --aks-rg <AKS resource group>
  12. The resource group for the AKS cluster. Required when the registry (using the -r parameter) is set to "aks".
  13. -c | --chart <name of chart>
  14. The name of the chart to upgrade (or install)
  15. -d | --dns <dns or ip address> | --dns aks
  16. Specifies the external DNS/ IP address of the Kubernetes cluster.
  17. If 'aks' is set as value, the DNS value is retrieved from the AKS. --aks-name and --aks-rg are needed.
  18. When --use-local-k8s is specified the external DNS is automatically set to localhost.
  19. -h | --help
  20. Displays this help text and exits the script.
  21. -n | --app-name <the name of the app>
  22. Specifies the name of the application (default: eshop).
  23. --namespace <namespace name>
  24. Specifies the namespace name to deploy the app. If it doesn't exists it will be created (default: eshop).
  25. -p | --docker-password <docker password>
  26. The Docker password used to logon to the custom registry, supplied using the -r parameter.
  27. -r | --registry <container registry>
  28. Specifies the container registry to use (required), e.g. myregistry.azurecr.io.
  29. --skip-clean
  30. Do not clean the Kubernetes helm chart. Default is to clean the chart.
  31. -t | --tag <docker image tag>
  32. The tag used for the newly created docker images. Default: latest.
  33. -u | --docker-username <docker username>
  34. The Docker username used to logon to the custom registry, supplied using the -r parameter.
  35. --use-local-k8s
  36. Deploy to a locally installed Kubernetes (default: false).
  37. It is assumed that the Kubernetes cluster has been granted access to the container registry.
  38. If using AKS and ACR see link for more info:
  39. https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-aks
  40. WARNING! THE SCRIPT WILL COMPLETELY DESTROY ALL DEPLOYMENTS AND SERVICES VISIBLE
  41. FROM THE CURRENT CONFIGURATION CONTEXT AND NAMESPACE.
  42. It is recommended that you check your selected namespace, 'eshop' by default, is already in use.
  43. Every deployment and service done in the namespace will be deleted.
  44. For more information see https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
  45. END
  46. }
  47. acr_connected=''
  48. app_name='eshop'
  49. aks_name=''
  50. aks_rg=''
  51. chart=''
  52. clean='yes'
  53. container_registry=''
  54. docker_password=''
  55. docker_username=''
  56. dns=''
  57. image_tag='latest'
  58. skip_infrastructure=''
  59. use_local_k8s=''
  60. namespace='eshop'
  61. while [[ $# -gt 0 ]]; do
  62. case "$1" in
  63. --acr-connected )
  64. acr_connected='yes'; shift ;;
  65. --aks-name )
  66. aks_name="$2"; shift 2;;
  67. --aks-rg )
  68. aks_rg="$2"; shift 2;;
  69. -c | --chart )
  70. chart="$2"; shift 2;;
  71. -d | --dns )
  72. dns="$2"; shift 2;;
  73. -h | --help )
  74. usage; exit 1 ;;
  75. -n | --app-name )
  76. app_name="$2"; shift 2;;
  77. -p | --docker-password )
  78. docker_password="$2"; shift 2;;
  79. -r | --registry )
  80. container_registry="$2"; shift 2;;
  81. --skip-clean )
  82. clean=''; shift ;;
  83. --image-build )
  84. build_images='yes'; shift ;;
  85. --image-push )
  86. push_images='yes'; shift ;;
  87. --skip-infrastructure )
  88. skip_infrastructure='yes'; shift ;;
  89. -t | --tag )
  90. image_tag="$2"; shift 2;;
  91. -u | --docker-username )
  92. docker_username="$2"; shift 2;;
  93. --use-local-k8s )
  94. use_local_k8s='yes'; shift ;;
  95. --namespace )
  96. namespace="$2"; shift 2;;
  97. *)
  98. echo "Unknown option $1"
  99. usage; exit 2 ;;
  100. esac
  101. done
  102. export TAG=$image_tag
  103. use_custom_registry=''
  104. if [[ -n $container_registry ]] && [[ -z $acr_connected ]]; then
  105. echo "################ Log into custom registry $container_registry ##################"
  106. use_custom_registry='yes'
  107. if [[ -z $docker_username ]] || [[ -z $docker_password ]]; then
  108. echo "Error: Must use -u (--docker-username) AND -p (--docker-password) if specifying custom registry"
  109. exit 1
  110. fi
  111. docker login -u $docker_username -p $docker_password $container_registry
  112. fi
  113. ingress_values_file="ingress_values.yaml"
  114. if [[ $use_local_k8s ]]; then
  115. ingress_values_file="ingress_values_dockerk8s.yaml"
  116. dns="localhost"
  117. fi
  118. if [[ $dns == "aks" ]]; then
  119. echo "#################### Begin AKS discovery based on the --dns aks setting. ####################"
  120. if [[ -z $aks_name ]] || [[ -z $aks_rg ]]; then
  121. echo "Error: When using -dns aks, MUST set -aksName and -aksRg too."
  122. echo ''
  123. usage
  124. exit 1
  125. fi
  126. echo "Getting AKS cluster $aks_name AKS (in resource group $aks_rg)"
  127. # JMESPath queries are case sensitive and httpapplicationrouting can be lowercase sometimes
  128. jmespath_dnsqueries=(\
  129. addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName \
  130. addonProfiles.httpapplicationrouting.config.HTTPApplicationRoutingZoneName \
  131. )
  132. for q in "${jmespath_dnsqueries[@]}"
  133. do
  134. dns="$(az aks show -n $aks_name -g $aks_rg --query $q -o tsv)"
  135. if [[ -n $dns ]]; then break; fi
  136. done
  137. if [[ -z $dns ]]; then
  138. echo "Error: when getting DNS of AKS $aks_name (in resource group $aks_rg). Please ensure AKS has httpRouting enabled AND Azure CLI is logged in and is of version 2.0.37 or higher."
  139. exit 1
  140. fi
  141. echo "DNS base found is $dns. Will use $aks_name.$dns for the app!"
  142. dns="$aks_name.$dns"
  143. fi
  144. # Initialization & check commands
  145. if [[ -z $dns ]]; then
  146. echo "No DNS specified. Ingress resources will be bound to public IP."
  147. fi
  148. previous_install=''
  149. if [[ -z $(helm ls -q --namespace $namespace | grep "$app_name-$chart") ]]; then
  150. echo "No previous release found"
  151. else
  152. previous_install='yes'
  153. fi
  154. if [[ $clean ]] && [[ $previous_install ]]; then
  155. echo "Cleaning previous helm releases..."
  156. helm uninstall "$app_name-$chart" --namespace $namespace
  157. echo "Previous release deleted"
  158. waitsecs=5; while [ $waitsecs -gt 0 ]; do echo -ne "$waitsecs\033[0K\r"; sleep 1; : $((waitsecs--)); done
  159. previous_install=''
  160. fi
  161. echo "#################### Begin $app_name $chart installation using Helm ####################"
  162. if [[ $use_custom_registry ]] || [[ $acr_connected ]]; then
  163. if [[ -z $acr_connected ]]; then
  164. if [[ -z $previous_install ]]; then
  165. helm upgrade --install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --set inf.registry.server=$container_registry --set inf.registry.login=$docker_username --set inf.registry.pwd=$docker_password --set inf.registry.secretName=eshop-docker-scret --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
  166. else
  167. helm upgrade --install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
  168. fi
  169. elif [[ $chart != "eshop-common" ]]; then
  170. # ACR is already connected, so we don't need username/password
  171. if [[ -z $previous_install ]]; then
  172. helm install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --set inf.registry.server=$container_registry --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
  173. else
  174. # don't set the image repo since it's already set
  175. helm upgrade "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
  176. fi
  177. fi
  178. elif [[ $chart != "eshop-common" ]]; then # eshop-common is ignored when no secret must be deployed
  179. helm upgrade --install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
  180. fi
  181. echo "FINISHED: Helm chart installed."