From aa79ff675b7d5f2ad9cd99e65ac8341708f47432 Mon Sep 17 00:00:00 2001 From: Kanika Pasrija Date: Wed, 22 Jan 2020 11:34:26 +0530 Subject: [PATCH 1/3] adding aks template --- .../templates/azurePipelineTemplates/aks.yml | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/configure/templates/azurePipelineTemplates/aks.yml diff --git a/src/configure/templates/azurePipelineTemplates/aks.yml b/src/configure/templates/azurePipelineTemplates/aks.yml new file mode 100644 index 00000000..fa9a74f0 --- /dev/null +++ b/src/configure/templates/azurePipelineTemplates/aks.yml @@ -0,0 +1,145 @@ +# Kubernetes Service on Azure +# Build an image and deploy it to Azure as Kubernetes service. +# Add steps that analyze code, save build artifacts, deploy, and more: +# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/dotnet-core + +trigger: +- {{{ sourceRepository.branch }}} + +variables: + # Azure Resource Manager connection created during pipeline creation + azureSubscription: '{{{ targetResource.serviceConnectionId }}}' + + # Kubernetes Service name + serviceName: '{{{ targetResource.resource.name }}}' + + # Agent VM image name + vmImageName: 'ubuntu-latest' + + containerRegistry : {FROM INPUTS}.azurecr.io //USER INPUT + kubernetesServiceConnection : {FROM inputs} //API CALL - ASSETS + namespace : {FROM inputs} //THIS CAN BE USERS - NAME - FROM CONFIG FILE + appName : {FROM inputs} //USER INPUT + dockerAuthSecretName : {} //SOME CONSTANT STANDARD STRING + imageName : '$(containerRegistry).azurecr.io/$(containerRegistry) ....$(Build.BuildId). : ' //NAME GENERATION USING MOUSTACHE HELPER + + # Working Directory + workingDirectory: '{{{ pipelineParameters.workingDirectory }}}' + + # Build Projects + dockerFile: "$(workingDirectory)/**/Dockerfile" + + +stages: +- stage: Build + displayName: Build stage + + jobs: + - job: Build + displayName: Build + pool: + vmImage: $(vmImageName) + + steps: + + - task: Docker@1 + displayName: 'Build an image' + inputs: + azureSubscriptionEndpoint: $(azureSubscription) + azureContainerRegistry: $(containerRegistry) + dockerFile: $(dockerFile) + imageName: $(imageName) + useDefaultContext: false + buildContext: Application + + - task: Docker@1 + displayName: 'Push an image' + inputs: + azureSubscriptionEndpoint: $(azureSubscription) + azureContainerRegistry: $(containerRegistry) + command: 'Push an image' + imageName: $(imageName) + + +- stage: Deploy + displayName: Deploy stage + dependsOn: Build + condition: succeeded() + + jobs: + - deployment: Deploy + displayName: Deploy + environment: $(appName) + pool: + vmImage: $(vmImageName) + strategy: + runOnce: + deploy: + steps: + - task: Kubernetes@1 + displayName: 'kubectl set imagePullSecrets' + inputs: + kubernetesServiceEndpoint: $(kubernetesServiceConnection) + namespace: $(namespace) + command: get + arguments: service + azureSubscriptionEndpointForSecrets: $(azureSubscription) + azureContainerRegistry: $(containerRegistry) + secretName: $(dockerAuthSecretName) + versionSpec: 1.10.12 + + - powershell: | + '# $(appName)/deployment.yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: $(appName) + labels: + app: $(appName) + spec: + replicas: 2 + selector: + matchLabels: + app: $(appName) + template: + metadata: + labels: + app: $(appName) + spec: + containers: + - name: $(appName) + image: $(imageName) + ports: + - name: http + containerPort: 80 + protocol: TCP + + --- + + # $(appName)/service.yaml + apiVersion: v1 + kind: Service + metadata: + name: $(appName) + labels: + app: $(appName) + spec: + type: LoadBalancer + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: $(appName)' | + Set-Content $(Agent.TempDirectory)/manifest.yaml + displayName: 'Generate Kubernetes Manifest file' + + - task: KubernetesManifest@0 + displayName: 'Kubernetes Manifest Deploy' + inputs: + kubernetesServiceConnection: $(kubernetesServiceConnection) + namespace: '$(namespace)' + manifests: '$(Agent.TempDirectory)/manifest.yaml' + imagePullSecrets: '$(dockerAuthSecretName)' + From 4666e896a97e58f4f6b6e5fa294c4594eade8680 Mon Sep 17 00:00:00 2001 From: Kanika Pasrija Date: Fri, 24 Jan 2020 14:33:44 +0530 Subject: [PATCH 2/3] adding template for github and changes in azure template --- .../templates/azurePipelineTemplates/aks.yml | 91 +++++++++--- .../githubWorkflowTemplates/aksGithub.yml | 134 ++++++++++++++++++ 2 files changed, 203 insertions(+), 22 deletions(-) create mode 100644 src/configure/templates/githubWorkflowTemplates/aksGithub.yml diff --git a/src/configure/templates/azurePipelineTemplates/aks.yml b/src/configure/templates/azurePipelineTemplates/aks.yml index fa9a74f0..032eac75 100644 --- a/src/configure/templates/azurePipelineTemplates/aks.yml +++ b/src/configure/templates/azurePipelineTemplates/aks.yml @@ -8,26 +8,26 @@ trigger: variables: # Azure Resource Manager connection created during pipeline creation - azureSubscription: '{{{ targetResource.serviceConnectionId }}}' + azureSubscription: '{{{ assets.serviceConnectionId }}}' # Kubernetes Service name - serviceName: '{{{ targetResource.resource.name }}}' + serviceName: '{{ #sanitizeString }} {{{ inputs.AKSresource.name }}} {{ /sanitizeString }}' # Agent VM image name vmImageName: 'ubuntu-latest' - containerRegistry : {FROM INPUTS}.azurecr.io //USER INPUT - kubernetesServiceConnection : {FROM inputs} //API CALL - ASSETS - namespace : {FROM inputs} //THIS CAN BE USERS - NAME - FROM CONFIG FILE - appName : {FROM inputs} //USER INPUT - dockerAuthSecretName : {} //SOME CONSTANT STANDARD STRING - imageName : '$(containerRegistry).azurecr.io/$(containerRegistry) ....$(Build.BuildId). : ' //NAME GENERATION USING MOUSTACHE HELPER + containerRegistry: '{{{ inputs.containerRegistry }}}.azurecr.io' + kubernetesServiceConnection: '{{{ assets.kubernetesServiceConnection }}}' + namespace: ' $(serviceName) {{#tinyguid}}{{/tinyguid}}' + appName: '$(serviceName)_{{#tinyguid}}{{/tinyguid}}' + dockerAuthSecretName: '$(serviceName)dockerauth' + imageName : "$(serviceName){{#tinyguid }}{{ /tinyguid }}" # Working Directory - workingDirectory: '{{{ pipelineParameters.workingDirectory }}}' + workingDirectory: '{{{ workingDirectory }}}' # Build Projects - dockerFile: "$(workingDirectory)/**/Dockerfile" + dockerFile: "$(workingDirectory)/Dockerfile" stages: @@ -111,27 +111,74 @@ stages: image: $(imageName) ports: - name: http - containerPort: 80 + containerPort: {{{ inputs.containerPort }}} protocol: TCP --- + {{#if}} {{{inputs.AKSresource.properties.addonProfiles.httpapplicationrouting.enabled}}} + # $(appName)/service.yaml apiVersion: v1 kind: Service metadata: - name: $(appName) - labels: - app: $(appName) + name: $(appName) + labels: + app: $(appName) spec: - type: LoadBalancer - ports: - - port: 80 - targetPort: http - protocol: TCP - name: http - selector: - app: $(appName)' | + type: ClusterIP + ports: + - port: {{{ inputs.containerPort }}} + targetPort: {{{ inputs.containerPort }}} + protocol: TCP + name: http + selector: + app: $(appName) + + --- + + # $(appName)/ingress.yaml + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: $(appName) + labels: + app: $(appName) + annotations: + kubernetes.io/ingress.class: addon-http-application-routing + spec: + rules: + - host: $(namespace)-$(appName).{{{inputs.AKSresource.properties.fqdn}}} + http: + paths: + - path: / + backend: + serviceName: $(appName) + servicePort: {{{ inputs.containerPort }}}' + + {{#else}} + + # $(appName)/service.yaml + apiVersion: v1 + kind: Service + metadata: + name: $(appName) + labels: + app: $(appName) + spec: + type: LoadBalancer + ports: + - port: {{{ inputs.containerPort }}} + targetPort: http + protocol: TCP + name: http + selector: + app: $(appName)' + + {{/if}} + + | + Set-Content $(Agent.TempDirectory)/manifest.yaml displayName: 'Generate Kubernetes Manifest file' diff --git a/src/configure/templates/githubWorkflowTemplates/aksGithub.yml b/src/configure/templates/githubWorkflowTemplates/aksGithub.yml new file mode 100644 index 00000000..1038db2e --- /dev/null +++ b/src/configure/templates/githubWorkflowTemplates/aksGithub.yml @@ -0,0 +1,134 @@ +on: [push] +jobs: + build-and-deploy: + env: + REGISTRY_URL: {{#toLower}} {{{inputs.containerRegistry}}} {{/toLower}}.azurecr.io + SERVICE_NAME: {{#sanitizeString}} {{{ inputs.AKSresource.name 50}}} {{/sanitizeString}} + NAMESPACE: $SERVICE_NAME{{#tinyguid}}{{/tinyguid}} + IMAGE_NAME: $SERVICE_NAME{{#tinyguid}}{{/tinyguid}} + APP_NAME: $(SERVICE_NAME)_{{#tinyguid}}{{/tinyguid}} + SECRET_NAME: {{#sanitizeString}} {{{ inputs.AKSresource.name 12}}} {{/sanitizeString}}dockerauth + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + + - uses: azure/docker-login@v1 + with: + login-server: $REGISTRY_URL + username: ${{ assets.REGISTRY_USERNAME }} + password: ${{ assets.REGISTRY_PASSWORD }} + + - name: Build and push image to ACR + id: build-image + run: | + docker build "$GITHUB_WORKSPACE/{{ workingDirectory }}" -f "{{ workingDirectory}}/Dockerfile" -t $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ <% github.sha %> }}<%={{ }}=%> + docker push $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ <% github.sha %> }}<%={{ }}=%> + + - uses: azure/k8s-set-context@v1 + with: + kubeconfig: ${{ secrets.KUBE_CONFIG }} + id: login + + - name: Create namespace + run: | + namespacePresent=`kubectl get namespace | grep $NAMESPACE | wc -l` + if [ $namespacePresent -eq 0 ] + then + echo `kubectl create namespace $NAMESPACE` + fi + + - uses: azure/k8s-create-secret@v1 + with: + namespace: $NAMESPACE + container-registry-url: $REGISTRY_URL + container-registry-username: ${{ assets.REGISTRY_USERNAME }} + container-registry-password: ${{ assets.REGISTRY_PASSWORD }} + secret-name: $SECRET_NAME + + - name: Generate Kubernetes Manifest file + id: manifest-creation + run: | + echo "apiVersion : apps/v1beta1 + kind: Deployment + metadata: + name: "$APP_NAME" + spec: + replicas: 2 + template: + metadata: + labels: + app: "$APP_NAME" + spec: + containers: + - name: "$APP_NAME" + image: "$REGISTRY_URL/$IMAGE_NAME" + ports: + - containerPort: {{{ inputs.containerPort }}} + + {{#if}} {{{inputs.AKSresource.properties.addonProfiles.httpapplicationrouting.enabled}}} + + apiVersion: v1 + kind: Service + metadata: + name: "$APP_NAME" + labels: + app: "$APP_NAME" + spec: + type: ClusterIP + ports: + - port: {{{ inputs.containerPort }}} + targetPort: {{{ inputs.containerPort }}} + protocol: TCP + name: http + selector: + app: "$APP_NAME" + + apiVersion: extensions/v1beta1 + kind: Ingress + metadata: + name: "$APP_NAME" + labels: + app: "$APP_NAME" + annotations: + kubernetes.io/ingress.class: addon-http-application-routing + spec: + rules: + - host: $NAMESPACE-$APP_NAME.{{{inputs.AKSresource.properties.fqdn}}} + http: + paths: + - path: / + backend: + serviceName: "$APP_NAME" + servicePort: {{{ inputs.containerPort }}}" + + {{#else}} + + apiVersion: v1 + kind: Service + metadata: + name: "$APP_NAME" + labels: + app: "$APP_NAME" + spec: + type: LoadBalancer + ports: + - port: {{{ inputs.containerPort }}} + targetPort: http + protocol: TCP + name: http + selector: + app: "$APP_NAME" + + {{/if}}" > manifest_{{{IMAGE_NAME}}}.yml + + + - uses: azure/k8s-deploy@v1 + with: + namespace: $NAMESPACE + manifests: | + {{{ GITHUB_WORKSPACE/manifest_{{{IMAGE_NAME}}}.yml }}} + images: | + $REGISTRY_URL/$IMAGE_NAME:{{=<% %>=}}${{ <% github.sha %> }}<%={{ }}=%> + imagepullsecrets: | + $SECRET_NAME \ No newline at end of file From 3479f929bbf7e8eeb802427faffb94030d19675e Mon Sep 17 00:00:00 2001 From: Kanika Pasrija Date: Fri, 24 Jan 2020 14:45:21 +0530 Subject: [PATCH 3/3] indendation correction --- src/configure/templates/azurePipelineTemplates/aks.yml | 4 ++-- src/configure/templates/githubWorkflowTemplates/aksGithub.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/configure/templates/azurePipelineTemplates/aks.yml b/src/configure/templates/azurePipelineTemplates/aks.yml index 032eac75..d649b386 100644 --- a/src/configure/templates/azurePipelineTemplates/aks.yml +++ b/src/configure/templates/azurePipelineTemplates/aks.yml @@ -18,10 +18,10 @@ variables: containerRegistry: '{{{ inputs.containerRegistry }}}.azurecr.io' kubernetesServiceConnection: '{{{ assets.kubernetesServiceConnection }}}' - namespace: ' $(serviceName) {{#tinyguid}}{{/tinyguid}}' + namespace: '$(serviceName) {{#tinyguid}}{{/tinyguid}}' appName: '$(serviceName)_{{#tinyguid}}{{/tinyguid}}' dockerAuthSecretName: '$(serviceName)dockerauth' - imageName : "$(serviceName){{#tinyguid }}{{ /tinyguid }}" + imageName: "$(serviceName){{#tinyguid }}{{ /tinyguid }}" # Working Directory workingDirectory: '{{{ workingDirectory }}}' diff --git a/src/configure/templates/githubWorkflowTemplates/aksGithub.yml b/src/configure/templates/githubWorkflowTemplates/aksGithub.yml index 1038db2e..b11f1049 100644 --- a/src/configure/templates/githubWorkflowTemplates/aksGithub.yml +++ b/src/configure/templates/githubWorkflowTemplates/aksGithub.yml @@ -5,7 +5,7 @@ jobs: REGISTRY_URL: {{#toLower}} {{{inputs.containerRegistry}}} {{/toLower}}.azurecr.io SERVICE_NAME: {{#sanitizeString}} {{{ inputs.AKSresource.name 50}}} {{/sanitizeString}} NAMESPACE: $SERVICE_NAME{{#tinyguid}}{{/tinyguid}} - IMAGE_NAME: $SERVICE_NAME{{#tinyguid}}{{/tinyguid}} + IMAGE_NAME: $SERVICE_NAME{{#tinyguid}}{{/tinyguid}} APP_NAME: $(SERVICE_NAME)_{{#tinyguid}}{{/tinyguid}} SECRET_NAME: {{#sanitizeString}} {{{ inputs.AKSresource.name 12}}} {{/sanitizeString}}dockerauth