diff --git a/README.md b/README.md index 46f293e7..13388012 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# VS Connected Environment -VSCE is an Azure developer service that helps teams develop with speed on Kubernetes. [Sign up for the private preview.](https://aka.ms/signup-vsce) +# Azure Dev Spaces +AZDS is an Azure developer service that helps teams develop with speed on Kubernetes. [Sign up for the private preview.](https://aka.ms/signup-azds) # Purpose of this repository -This source repository primarily hosts *VSCE code samples* to support product guides, as well as provide high-level insight into our product roadmap. Product documentation is hosted here: http://aka.ms/get-vsce. +This source repository primarily hosts *AZDS code samples* to support product guides, as well as provide high-level insight into our product roadmap. Product documentation is hosted here: http://aka.ms/get-azds. # Contributing diff --git a/roadmap.md b/roadmap.md index 2b76c92c..e598a55c 100644 --- a/roadmap.md +++ b/roadmap.md @@ -1,5 +1,5 @@ -# VS Connected Environment Roadmap -VSCE is an Azure developer service that enables a fast, iterative development experience for Kubernetes. Teams can work within the same Connected Environment, and test code end-to-end without simulating or mocking dependencies. +# Azure Dev Spaces Roadmap +AZDS is an Azure developer service that enables a fast, iterative development experience for Kubernetes. Teams can work within the same Azure Dev Spaces, and test code end-to-end without simulating or mocking dependencies. These are examples of the work we will be focusing on in the next 3-6 months. It is not a complete list, but it is a good reflection of our direction. We continuously tune the plan based on feedback. Please follow along and let us know what you think! @@ -7,28 +7,19 @@ These are examples of the work we will be focusing on in the next 3-6 months. It ## Inner loop performance ![Ongoing work](https://placehold.it/15/1589F0/000000?text=+) -Providing a fast, iterative development experience is at the heart of VSCE. We aspire to make the inner loop performance and workflow for VSCE as close to local development as possible. We recently made significant improvements to .NET Core debug performance in VS Code, and we're currenty working on applying this to Visual Studio 2017. - +Providing a fast, iterative development experience is at the heart of AZDS. We aspire to make the inner loop performance and workflow for AZDS as close to local development as possible. We recently made significant improvements to .NET Core debug performance in VS Code, and we're currenty working on applying this to Visual Studio 2017. + ## Improve experience for project references ![Ongoing work](https://placehold.it/15/1589F0/000000?text=+) It is currently not straightforward to successfully F5/debug projects that have VS project-to-project references. We want to streamline this experience for common VS solution structure patterns. - -## Azure portal experience -Provide an experience for creating, sharing, and managing Connected Environments in the [Azure portal](https://portal.azure.com). - -## Custom Virtual Network support ![Ongoing work](https://placehold.it/15/1589F0/000000?text=+) -The ability to place a Connected Environment, at the time of creation, into an existing Virtual Network. Two key scenarios: 1) Containers running in the Kubernetes cluster need to access Azure services, like SQL and Redis, that are provisioned in an existing VNet. 2) Lock down VSCE endpoints so that they are only accessible from inside the VNet. - -## Connected Environment size and customization ![Ongoing work](https://placehold.it/15/1589F0/000000?text=+) -Provide a way to specify Kubernetes cluster size to best fit budget and workload requirements. We are also considering support for connecting VSCE to an existing AKS instance for more flexibility. + +## Azure Portal experience +Provide an experience for creating, sharing, and managing Azure Dev Spaces in the [Azure portal](https://portal.azure.com). ## Enable non-http protocols ![Ongoing work](https://placehold.it/15/1589F0/000000?text=+) Loosen requirements on service-to-service communication to allow raw TCP, websockets, etc. ## Java debugging Support a Kubernetes debugging experience for Java containers, similar to current support for .NET Core and Node.js code. - -## Expand Azure regions -VSCE is currently available in `eastus` and `westeurope`. More regions will be added based on usage patterns. - + ## Publish to AKS from Visual Studio Provide a familiar experience for publishing a project to AKS via the Visual Studio publish wizard, as defined by the Dockerfile and Helm chart assets in the project. A related scenario under consideration is publishing a solution (of multiple projects). diff --git a/samples/dotnetcore/getting-started/mywebapi/.dockerignore b/samples/dotnetcore/getting-started/mywebapi/.dockerignore index 02836c9a..32a04ef1 100644 --- a/samples/dotnetcore/getting-started/mywebapi/.dockerignore +++ b/samples/dotnetcore/getting-started/mywebapi/.dockerignore @@ -3,10 +3,12 @@ .gitignore .vs .vscode -*.*proj.user -bin -charts -Dockerfile -Dockerfile.develop -obj -vsce.yaml \ No newline at end of file +**/*.*proj.user +**/bin +**/charts +**/Dockerfile +**/Dockerfile.develop +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +**/azds.yaml \ No newline at end of file diff --git a/samples/dotnetcore/getting-started/mywebapi/.vscode/launch.json b/samples/dotnetcore/getting-started/mywebapi/.vscode/launch.json index 126d5275..f128d37e 100644 --- a/samples/dotnetcore/getting-started/mywebapi/.vscode/launch.json +++ b/samples/dotnetcore/getting-started/mywebapi/.vscode/launch.json @@ -1,23 +1,24 @@ { "configurations": [ { - "name": ".NET Core Launch (VSCE)", + "name": ".NET Core Launch (AZDS)", "type": "coreclr", "request": "launch", - "preLaunchTask": "build (VSCE)", + "preLaunchTask": "build (AZDS)", "cwd": "/src", "program": "/src/bin/Debug/netcoreapp2.0/mywebapi.dll", "sourceFileMap": { "/src": "${workspaceRoot}" }, "pipeTransport": { - "pipeProgram": "vsce", + "pipeProgram": "azds", "pipeCwd": "${workspaceRoot}", "debuggerPath": "/vsdbg/vsdbg", "pipeArgs": [ "exec", "-i", "--restore-command", + "--no-telemetry", "--" ], "quoteArgs": false diff --git a/samples/dotnetcore/getting-started/mywebapi/.vscode/tasks.json b/samples/dotnetcore/getting-started/mywebapi/.vscode/tasks.json index b7658323..86ab863b 100644 --- a/samples/dotnetcore/getting-started/mywebapi/.vscode/tasks.json +++ b/samples/dotnetcore/getting-started/mywebapi/.vscode/tasks.json @@ -1,12 +1,13 @@ { "tasks": [ { - "label": "build (VSCE)", - "command": "vsce", + "label": "build (AZDS)", + "command": "azds", "args": [ "up", "--iterate", - "--no-command" + "--no-command", + "--no-telemetry" ], "options": { "cwd": "${workspaceRoot}" diff --git a/samples/dotnetcore/getting-started/mywebapi/Dockerfile b/samples/dotnetcore/getting-started/mywebapi/Dockerfile index dd3e0fe2..124c73ce 100644 --- a/samples/dotnetcore/getting-started/mywebapi/Dockerfile +++ b/samples/dotnetcore/getting-started/mywebapi/Dockerfile @@ -14,4 +14,4 @@ RUN dotnet publish mywebapi.csproj -c Release -o /app FROM base AS final COPY --from=publish /app . -ENTRYPOINT ["dotnet", "mywebapi.dll"] +ENTRYPOINT ["dotnet", "mywebapi.dll"] \ No newline at end of file diff --git a/samples/dotnetcore/getting-started/mywebapi/Dockerfile.develop b/samples/dotnetcore/getting-started/mywebapi/Dockerfile.develop index c50d323c..c43c2626 100644 --- a/samples/dotnetcore/getting-started/mywebapi/Dockerfile.develop +++ b/samples/dotnetcore/getting-started/mywebapi/Dockerfile.develop @@ -6,7 +6,7 @@ EXPOSE 80 WORKDIR /src COPY mywebapi.csproj . -RUN dotnet restore +RUN dotnet restore -nowarn:msb3202,nu1503 COPY . . RUN dotnet build diff --git a/samples/dotnetcore/getting-started/mywebapi/vsce.yaml b/samples/dotnetcore/getting-started/mywebapi/azds.yaml similarity index 66% rename from samples/dotnetcore/getting-started/mywebapi/vsce.yaml rename to samples/dotnetcore/getting-started/mywebapi/azds.yaml index fb8128a7..95441887 100644 --- a/samples/dotnetcore/getting-started/mywebapi/vsce.yaml +++ b/samples/dotnetcore/getting-started/mywebapi/azds.yaml @@ -1,19 +1,26 @@ kind: helm-release +apiVersion: 1.0 build: context: . dockerfile: Dockerfile install: chart: charts/mywebapi + values: + - values.dev.yaml? + - secrets.dev.yaml? set: image: tag: $(tag) pullPolicy: Never - # This ingress section specifies whether VSCE should expose a secure - # public development endpoint like https://mywebapi-myenv.vsce.io + disableProbes: true + # This ingress section specifies whether AZDS should expose + # an endpoint like http://mywebapi...aksapp.io # ingress: # enabled: true + # hosts: + # - $(spacePrefix)mywebapi$(hostSuffix) # annotations: - # kubernetes.io/ingress.class: vsce + # kubernetes.io/ingress.class: addon-http-application-routing configurations: develop: build: diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/Chart.yaml b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/Chart.yaml index b79f0c39..7bd5c82e 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/Chart.yaml +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/Chart.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +appVersion: "1.0" description: A Helm chart for Kubernetes name: mywebapi version: 0.1.0 diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt index c4e21460..cb3f26d5 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt @@ -1,7 +1,7 @@ 1. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} {{- range .Values.ingress.hosts }} - http://{{ . }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} {{- end }} {{- else if contains "NodePort" .Values.service.type }} export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "mywebapi.fullname" . }}) @@ -11,9 +11,9 @@ NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get svc -w {{ template "mywebapi.fullname" . }}' export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "mywebapi.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.service.externalPort }} + echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "mywebapi.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} + kubectl port-forward $POD_NAME 8080:80 {{- end }} diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl index c7ccfc74..3c8a6451 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl @@ -9,15 +9,24 @@ Expand the name of the chart. {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. */}} {{- define "mywebapi.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} {{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}} +{{- end -}} +{{- end -}} {{/* -Create a default service name. +Create chart name and version as used by the chart label. */}} -{{- define "mywebapi.servicename" -}} -{{ if .Values.service.singleton }}{{ .Values.service.name }}{{ else }}{{ template "mywebapi.fullname" . }}{{ end }} +{{- define "mywebapi.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml index e689ae80..b6f3d0b8 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml @@ -1,14 +1,18 @@ -apiVersion: extensions/v1beta1 +apiVersion: apps/v1beta2 kind: Deployment metadata: name: {{ template "mywebapi.fullname" . }} labels: app: {{ template "mywebapi.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + chart: {{ template "mywebapi.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "mywebapi.name" . }} + release: {{ .Release.Name }} template: metadata: labels: @@ -20,7 +24,19 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - - containerPort: {{ .Values.service.internalPort }} + - name: http + containerPort: 80 + protocol: TCP + {{- if not .Values.disableProbes }} + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + {{- end }} env: {{- $root := . }} {{- range $ref, $values := .Values.secrets }} @@ -32,21 +48,21 @@ spec: key: {{ $key }} {{- end }} {{- end }} - # livenessProbe: - # httpGet: - # path: / - # port: {{ .Values.service.internalPort }} - # readinessProbe: - # httpGet: - # path: / - # port: {{ .Values.service.internalPort }} resources: {{ toYaml .Values.resources | indent 12 }} - {{- if .Values.imagePullSecrets }} + {{- with .Values.imagePullSecrets }} imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{ toYaml . | indent 8 }} {{- end }} - {{- if .Values.nodeSelector }} + {{- with .Values.nodeSelector }} nodeSelector: -{{ toYaml .Values.nodeSelector | indent 8 }} +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} {{- end }} diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml index 152fa005..24a69fdd 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml @@ -1,32 +1,39 @@ {{- if .Values.ingress.enabled -}} -{{- $serviceName := include "mywebapi.servicename" . -}} -{{- $servicePort := .Values.service.externalPort -}} +{{- $fullName := include "mywebapi.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} apiVersion: extensions/v1beta1 kind: Ingress metadata: - name: {{ template "mywebapi.fullname" . }} + name: {{ $fullName }} labels: app: {{ template "mywebapi.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + chart: {{ template "mywebapi.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} +{{- with .Values.ingress.annotations }} annotations: - {{- range $key, $value := .Values.ingress.annotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} +{{ toYaml . | indent 4 }} +{{- end }} spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} rules: - {{- range $host := .Values.ingress.hosts }} - - host: {{ $host }} + {{- range .Values.ingress.hosts }} + - host: {{ . }} http: paths: - - path: / + - path: {{ $ingressPath }} backend: - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end -}} - {{- if .Values.ingress.tls }} - tls: -{{ toYaml .Values.ingress.tls | indent 4 }} - {{- end -}} -{{- end -}} + serviceName: {{ $fullName }} + servicePort: http + {{- end }} +{{- end }} diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/service.yaml b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/service.yaml index 0e147700..d6865802 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/service.yaml +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/templates/service.yaml @@ -1,19 +1,19 @@ apiVersion: v1 kind: Service metadata: - name: {{ template "mywebapi.servicename" . }} + name: {{ template "mywebapi.fullname" . }} labels: app: {{ template "mywebapi.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + chart: {{ template "mywebapi.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.externalPort }} - targetPort: {{ .Values.service.internalPort }} + - port: {{ .Values.service.port }} + targetPort: http protocol: TCP - name: {{ .Values.service.name }} + name: http selector: app: {{ template "mywebapi.name" . }} release: {{ .Release.Name }} diff --git a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/values.yaml b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/values.yaml index d9c4094f..f050cec4 100644 --- a/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/values.yaml +++ b/samples/dotnetcore/getting-started/mywebapi/charts/mywebapi/values.yaml @@ -1,35 +1,47 @@ # Default values for mywebapi. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +fullnameOverride: mywebapi replicaCount: 1 image: repository: mywebapi tag: stable pullPolicy: IfNotPresent -# Optionally specify an array of imagePullSecrets. -# Secrets must be manually created in the namespace. -# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod -# imagePullSecrets: -# - name: myRegistryKeySecretName +imagePullSecrets: [] + # Optionally specify an array of imagePullSecrets. + # Secrets must be manually created in the namespace. + # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + # + # This uses credentials from secret "myRegistryKeySecretName". + # - name: myRegistryKeySecretName service: - name: mywebapi type: ClusterIP - externalPort: 80 - internalPort: 80 - singleton: true + port: 80 + ingress: enabled: false - # Used to create an Ingress record. - hosts: - - mywebapi - annotations: + annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" - tls: - # Secrets must be manually created in the namespace. + path: / + hosts: + - chart-example.local + tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local +secrets: {} + # Optionally specify a set of secret objects whose values + # will be injected as environment variables by default. + # You should add this section to a file like secrets.yaml + # that is explicitly NOT committed to source code control + # and then include it as part of your helm install step. + # ref: https://kubernetes.io/docs/concepts/configuration/secret/ + # + # This creates a secret "mysecret" and injects "mypassword" + # as the environment variable MYSECRET_MYPASSWORD=123. + # mysecret: + # mypassword: 123 resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little @@ -41,3 +53,8 @@ resources: {} # requests: # cpu: 100m # memory: 128Mi +nodeSelector: {} + +tolerations: [] + +affinity: {} \ No newline at end of file diff --git a/samples/dotnetcore/getting-started/mywebapi/launch.json b/samples/dotnetcore/getting-started/mywebapi/launch.json deleted file mode 100644 index f186dc33..00000000 --- a/samples/dotnetcore/getting-started/mywebapi/launch.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "configurations": [ - { - "name": ".NET Core Launch (VSCE)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build (VSCE)", - "cwd": "/src", - "program": "/src/bin/Debug/netcoreapp2.0/mywebapi.dll", - "sourceFileMap": { - "/src": "${workspaceRoot}" - }, - "pipeTransport": { - "pipeProgram": "vsce", - "pipeCwd": "${workspaceRoot}", - "debuggerPath": "/vsdbg/vsdbg", - "pipeArgs": [ - "exec", - "-i" - ] - } - } - ] -} \ No newline at end of file diff --git a/samples/dotnetcore/getting-started/mywebapi/tasks.json b/samples/dotnetcore/getting-started/mywebapi/tasks.json deleted file mode 100644 index fc90cb40..00000000 --- a/samples/dotnetcore/getting-started/mywebapi/tasks.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "tasks": [ - { - "label": "build (VSCE)", - "dependsOn": "vsce: ready", - "command": "vsce", - "args": [ - "exec", - "--kill", - "dotnet", - "--", - "dotnet", - "build" - ], - "options": { - "cwd": "${workspaceRoot}" - }, - "presentation": { - "panel": "dedicated" - }, - "problemMatcher": "$msCompile" - }, - { - "label": "vsce: ready", - "command": "vsce", - "args": [ - "up", - "--incremental", - "--no-command", - "--sync", - "!**/*.{sln,csproj}", - "--detach" - ], - "options": { - "cwd": "${workspaceRoot}" - }, - "presentation": { - "panel": "dedicated" - }, - "problemMatcher": [] - } - ] -} \ No newline at end of file diff --git a/samples/nodejs/getting-started/mywebapi/.dockerignore b/samples/nodejs/getting-started/mywebapi/.dockerignore index f3e16620..d8e04959 100644 --- a/samples/nodejs/getting-started/mywebapi/.dockerignore +++ b/samples/nodejs/getting-started/mywebapi/.dockerignore @@ -6,4 +6,6 @@ charts Dockerfile node_modules -vsce.yaml +secrets.dev.yaml +values.dev.yaml +azds.yaml diff --git a/samples/nodejs/getting-started/mywebapi/.vscode/launch.json b/samples/nodejs/getting-started/mywebapi/.vscode/launch.json index d75632e9..43af11da 100644 --- a/samples/nodejs/getting-started/mywebapi/.vscode/launch.json +++ b/samples/nodejs/getting-started/mywebapi/.vscode/launch.json @@ -1,22 +1,23 @@ { "configurations": [ { - "name": "Launch Program (VSCE)", + "name": "Launch Program (AZDS)", "type": "node", "request": "launch", "protocol": "inspector", - "preLaunchTask": "vsce: ready", + "preLaunchTask": "azds: ready", "cwd": "${workspaceRoot}", - "port": 54159, + "port": 56624, "address": "127.0.0.1", "localRoot": "${workspaceRoot}", "remoteRoot": "/app", - "runtimeExecutable": "vsce", + "runtimeExecutable": "azds", "runtimeArgs": [ "exec", "--config", "develop", "--restore-command", + "--no-telemetry", "--", "node", "--inspect=0.0.0.0:9229", @@ -27,13 +28,13 @@ "timeout": 30000 }, { - "name": "Attach (VSCE)", + "name": "Attach (AZDS)", "type": "node", "request": "attach", "protocol": "inspector", - "preLaunchTask": "nodemon: server.js (VSCE)", + "preLaunchTask": "nodemon: server.js (AZDS)", "cwd": "${workspaceRoot}", - "port": 54159, + "port": 56624, "address": "127.0.0.1", "localRoot": "${workspaceRoot}", "remoteRoot": "/app", diff --git a/samples/nodejs/getting-started/mywebapi/.vscode/tasks.json b/samples/nodejs/getting-started/mywebapi/.vscode/tasks.json index 163ff703..c33d47af 100644 --- a/samples/nodejs/getting-started/mywebapi/.vscode/tasks.json +++ b/samples/nodejs/getting-started/mywebapi/.vscode/tasks.json @@ -1,16 +1,17 @@ { "tasks": [ { - "label": "vsce: ready", - "command": "vsce", + "label": "azds: ready", + "command": "azds", "args": [ "up", "--iterate", "--port", - "54159:9229", + "56624:9229", "--no-command", "--config", "develop", + "--no-telemetry", "--", "npm", "start" @@ -21,15 +22,16 @@ "problemMatcher": [] }, { - "label": "nodemon: server.js (VSCE)", - "command": "vsce", + "label": "nodemon: server.js (AZDS)", + "command": "azds", "args": [ "up", "--iterate", "--port", - "54159:9229", + "56624:9229", "--config", "develop.attach", + "--no-telemetry", "--", "node_modules/.bin/nodemon", "--inspect=0.0.0.0:9229", diff --git a/samples/nodejs/getting-started/mywebapi/Dockerfile b/samples/nodejs/getting-started/mywebapi/Dockerfile index 0cf40f22..8db8c92c 100644 --- a/samples/nodejs/getting-started/mywebapi/Dockerfile +++ b/samples/nodejs/getting-started/mywebapi/Dockerfile @@ -1,5 +1,6 @@ FROM node EXPOSE 80 +ENV PORT 80 WORKDIR /app COPY package.json . diff --git a/samples/nodejs/getting-started/mywebapi/vsce.yaml b/samples/nodejs/getting-started/mywebapi/azds.yaml similarity index 57% rename from samples/nodejs/getting-started/mywebapi/vsce.yaml rename to samples/nodejs/getting-started/mywebapi/azds.yaml index 8cc96ef2..f0b2e886 100644 --- a/samples/nodejs/getting-started/mywebapi/vsce.yaml +++ b/samples/nodejs/getting-started/mywebapi/azds.yaml @@ -1,18 +1,26 @@ kind: helm-release +apiVersion: 1.0 build: context: . + dockerfile: Dockerfile install: chart: charts/mywebapi + values: + - values.dev.yaml? + - secrets.dev.yaml? set: image: tag: $(tag) pullPolicy: Never - # This ingress section specifies whether VSCE should expose a secure - # public development endpoint like https://mywebapi-myenv.vsce.io + disableProbes: true + # This ingress section specifies whether AZDS should expose + # an endpoint like http://mywebapi...aksapp.io # ingress: # enabled: true + # hosts: + # - $(spacePrefix)mywebapi$(hostSuffix) # annotations: - # kubernetes.io/ingress.class: vsce + # kubernetes.io/ingress.class: addon-http-application-routing configurations: develop: build: diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/Chart.yaml b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/Chart.yaml index b79f0c39..7bd5c82e 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/Chart.yaml +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/Chart.yaml @@ -1,4 +1,5 @@ apiVersion: v1 +appVersion: "1.0" description: A Helm chart for Kubernetes name: mywebapi version: 0.1.0 diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt index c4e21460..cb3f26d5 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/NOTES.txt @@ -1,7 +1,7 @@ 1. Get the application URL by running these commands: {{- if .Values.ingress.enabled }} {{- range .Values.ingress.hosts }} - http://{{ . }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} {{- end }} {{- else if contains "NodePort" .Values.service.type }} export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "mywebapi.fullname" . }}) @@ -11,9 +11,9 @@ NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get svc -w {{ template "mywebapi.fullname" . }}' export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "mywebapi.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - echo http://$SERVICE_IP:{{ .Values.service.externalPort }} + echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "mywebapi.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") echo "Visit http://127.0.0.1:8080 to use your application" - kubectl port-forward $POD_NAME 8080:{{ .Values.service.internalPort }} + kubectl port-forward $POD_NAME 8080:80 {{- end }} diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl index c7ccfc74..3c8a6451 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/_helpers.tpl @@ -9,15 +9,24 @@ Expand the name of the chart. {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. */}} {{- define "mywebapi.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} {{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}} +{{- end -}} +{{- end -}} {{/* -Create a default service name. +Create chart name and version as used by the chart label. */}} -{{- define "mywebapi.servicename" -}} -{{ if .Values.service.singleton }}{{ .Values.service.name }}{{ else }}{{ template "mywebapi.fullname" . }}{{ end }} +{{- define "mywebapi.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml index e689ae80..b6f3d0b8 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/deployment.yaml @@ -1,14 +1,18 @@ -apiVersion: extensions/v1beta1 +apiVersion: apps/v1beta2 kind: Deployment metadata: name: {{ template "mywebapi.fullname" . }} labels: app: {{ template "mywebapi.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + chart: {{ template "mywebapi.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "mywebapi.name" . }} + release: {{ .Release.Name }} template: metadata: labels: @@ -20,7 +24,19 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - - containerPort: {{ .Values.service.internalPort }} + - name: http + containerPort: 80 + protocol: TCP + {{- if not .Values.disableProbes }} + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + {{- end }} env: {{- $root := . }} {{- range $ref, $values := .Values.secrets }} @@ -32,21 +48,21 @@ spec: key: {{ $key }} {{- end }} {{- end }} - # livenessProbe: - # httpGet: - # path: / - # port: {{ .Values.service.internalPort }} - # readinessProbe: - # httpGet: - # path: / - # port: {{ .Values.service.internalPort }} resources: {{ toYaml .Values.resources | indent 12 }} - {{- if .Values.imagePullSecrets }} + {{- with .Values.imagePullSecrets }} imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{ toYaml . | indent 8 }} {{- end }} - {{- if .Values.nodeSelector }} + {{- with .Values.nodeSelector }} nodeSelector: -{{ toYaml .Values.nodeSelector | indent 8 }} +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} {{- end }} diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml index 152fa005..24a69fdd 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/ingress.yaml @@ -1,32 +1,39 @@ {{- if .Values.ingress.enabled -}} -{{- $serviceName := include "mywebapi.servicename" . -}} -{{- $servicePort := .Values.service.externalPort -}} +{{- $fullName := include "mywebapi.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} apiVersion: extensions/v1beta1 kind: Ingress metadata: - name: {{ template "mywebapi.fullname" . }} + name: {{ $fullName }} labels: app: {{ template "mywebapi.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + chart: {{ template "mywebapi.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} +{{- with .Values.ingress.annotations }} annotations: - {{- range $key, $value := .Values.ingress.annotations }} - {{ $key }}: {{ $value | quote }} - {{- end }} +{{ toYaml . | indent 4 }} +{{- end }} spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} rules: - {{- range $host := .Values.ingress.hosts }} - - host: {{ $host }} + {{- range .Values.ingress.hosts }} + - host: {{ . }} http: paths: - - path: / + - path: {{ $ingressPath }} backend: - serviceName: {{ $serviceName }} - servicePort: {{ $servicePort }} - {{- end -}} - {{- if .Values.ingress.tls }} - tls: -{{ toYaml .Values.ingress.tls | indent 4 }} - {{- end -}} -{{- end -}} + serviceName: {{ $fullName }} + servicePort: http + {{- end }} +{{- end }} diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/service.yaml b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/service.yaml index 0e147700..d6865802 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/service.yaml +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/templates/service.yaml @@ -1,19 +1,19 @@ apiVersion: v1 kind: Service metadata: - name: {{ template "mywebapi.servicename" . }} + name: {{ template "mywebapi.fullname" . }} labels: app: {{ template "mywebapi.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + chart: {{ template "mywebapi.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: type: {{ .Values.service.type }} ports: - - port: {{ .Values.service.externalPort }} - targetPort: {{ .Values.service.internalPort }} + - port: {{ .Values.service.port }} + targetPort: http protocol: TCP - name: {{ .Values.service.name }} + name: http selector: app: {{ template "mywebapi.name" . }} release: {{ .Release.Name }} diff --git a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/values.yaml b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/values.yaml index d9c4094f..f050cec4 100644 --- a/samples/nodejs/getting-started/mywebapi/charts/mywebapi/values.yaml +++ b/samples/nodejs/getting-started/mywebapi/charts/mywebapi/values.yaml @@ -1,35 +1,47 @@ # Default values for mywebapi. # This is a YAML-formatted file. # Declare variables to be passed into your templates. +fullnameOverride: mywebapi replicaCount: 1 image: repository: mywebapi tag: stable pullPolicy: IfNotPresent -# Optionally specify an array of imagePullSecrets. -# Secrets must be manually created in the namespace. -# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod -# imagePullSecrets: -# - name: myRegistryKeySecretName +imagePullSecrets: [] + # Optionally specify an array of imagePullSecrets. + # Secrets must be manually created in the namespace. + # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + # + # This uses credentials from secret "myRegistryKeySecretName". + # - name: myRegistryKeySecretName service: - name: mywebapi type: ClusterIP - externalPort: 80 - internalPort: 80 - singleton: true + port: 80 + ingress: enabled: false - # Used to create an Ingress record. - hosts: - - mywebapi - annotations: + annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" - tls: - # Secrets must be manually created in the namespace. + path: / + hosts: + - chart-example.local + tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local +secrets: {} + # Optionally specify a set of secret objects whose values + # will be injected as environment variables by default. + # You should add this section to a file like secrets.yaml + # that is explicitly NOT committed to source code control + # and then include it as part of your helm install step. + # ref: https://kubernetes.io/docs/concepts/configuration/secret/ + # + # This creates a secret "mysecret" and injects "mypassword" + # as the environment variable MYSECRET_MYPASSWORD=123. + # mysecret: + # mypassword: 123 resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little @@ -41,3 +53,8 @@ resources: {} # requests: # cpu: 100m # memory: 128Mi +nodeSelector: {} + +tolerations: [] + +affinity: {} \ No newline at end of file