diff --git a/deploy/addons/ambassador/ambassador-operator-crds.yaml b/deploy/addons/ambassador/ambassador-operator-crds.yaml
new file mode 100644
index 000000000000..287b706639f3
--- /dev/null
+++ b/deploy/addons/ambassador/ambassador-operator-crds.yaml
@@ -0,0 +1,186 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: ambassadorinstallations.getambassador.io
+spec:
+ additionalPrinterColumns:
+ - JSONPath: .spec.version
+ name: VERSION
+ type: string
+ - JSONPath: .spec.updateWindow
+ name: UPDATE-WINDOW
+ type: integer
+ - JSONPath: .status.lastCheckTime
+ description: Last time checked
+ name: LAST-CHECK
+ type: string
+ - JSONPath: .status.conditions[?(@.type=='Deployed')].status
+ description: Indicates if deployment has completed
+ name: DEPLOYED
+ type: string
+ - JSONPath: .status.conditions[?(@.type=='Deployed')].reason
+ description: Reason for deployment completed
+ name: REASON
+ priority: 1
+ type: string
+ - JSONPath: .status.conditions[?(@.type=='Deployed')].message
+ description: Message for deployment completed
+ name: MESSAGE
+ priority: 1
+ type: string
+ - JSONPath: .status.deployedRelease.appVersion
+ description: Deployed version of Ambassador
+ name: DEPLOYED-VERSION
+ type: string
+ - JSONPath: .status.deployedRelease.flavor
+ description: Deployed flavor of Ambassador (OSS or AES)
+ name: DEPLOYED-FLAVOR
+ type: string
+ group: getambassador.io
+ names:
+ kind: AmbassadorInstallation
+ listKind: AmbassadorInstallationList
+ plural: ambassadorinstallations
+ singular: ambassadorinstallation
+ scope: Namespaced
+ subresources:
+ status: {}
+ validation:
+ openAPIV3Schema:
+ description: AmbassadorInstallation is the Schema for the ambassadorinstallations
+ API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: AmbassadorInstallationSpec defines the desired state of AmbassadorInstallation
+ properties:
+ baseImage:
+ description: An (optional) image to use instead of the image specified
+ in the Helm chart.
+ type: string
+ helmRepo:
+ description: An (optional) Helm repository.
+ type: string
+ installOSS:
+ description: 'Installs [Ambassador OSS](https://www.getambassador.io/docs/latest/topics/install/install-ambassador-oss/)
+ instead of [AES](https://www.getambassador.io/docs/latest/topics/install/).
+ Default is false which means it installs AES by default. TODO: 1.
+ AES/AOSS is not installed and the user installs using `installOSS:
+ true`, then we straightaway install AOSS. 2. AOSS is installed via
+ operator and the user sets `installOSS: false`, then we perform the
+ migration as detailed here - https://www.getambassador.io/docs/latest/topics/install/upgrade-to-edge-stack/
+ 3. AES is installed and the user sets `installOSS: true`, then we
+ point users to the docs which gives them pointers on how to do
+ that themselves.'
+ type: boolean
+ logLevel:
+ description: 'An (optional) log level: debug, info...'
+ enum:
+ - info
+ - debug
+ - warn
+ - warning
+ - error
+ - critical
+ - fatal
+ type: string
+ updateWindow:
+ description: "`updateWindow` is an optional item that will control when
+ the updates can take place. This is used to force system updates to
+ happen late at night if that’s what the sysadmins want. \n * There
+ can be any number of `updateWindow` entries (separated by commas).
+ \ * `Never` turns off automatic updates even if there are other entries
+ in the comma-separated list. `Never` is used by sysadmins to disable
+ all updates during blackout periods by doing a `kubectl apply`
+ or using our Edge Policy Console to set this. * Each `updateWindow`
+ is in crontab format (see https://crontab.guru/) Some examples of
+ `updateWindows` are: - `* 0-6 * * * SUN`: every Sunday, from _0am_
+ to _6am_ - `* 5 1 * * *`: every first day of the month, at _5am_
+ * The Operator cannot guarantee minute time granularity, so specifying
+ \ a minute in the crontab expression can lead to some updates happening
+ \ sooner/later than expected."
+ type: string
+ version:
+ description: "We are using SemVer for the version number and it can
+ be specified with any level of precision and can optionally end in
+ `*`. These are interpreted as: \n * `1.0` = exactly version 1.0 *
+ `1.1` = exactly version 1.1 * `1.1.*` = version 1.1 and any bug fix
+ versions `1.1.1`, `1.1.2`, `1.1.3`, etc. * `2.*` = version 2.0 and
+ any incremental and bug fix versions `2.0`, `2.0.1`, `2.0.2`, `2.1`,
+ `2.2`, `2.2.1`, etc. * `*` = all versions. * `3.0-ea` = version `3.0-ea1`
+ and any subsequent EA releases on `3.0`. Also selects the final
+ 3.0 once the final GA version is released. * `4.*-ea` = version `4.0-ea1`
+ and any subsequent EA release on `4.0`. Also selects the final GA
+ `4.0`. Also selects any incremental and bug fix versions `4.*` and
+ `4.*.*`. Also selects the most recent `4.*` EA release i.e., if
+ `4.0.5` is the last GA version and there is a `4.1-EA3`, then this
+ \ selects `4.1-EA3` over the `4.0.5` GA. \n You can find the reference
+ docs about the SemVer syntax accepted [here](https://github.com/Masterminds/semver#basic-comparisons)."
+ type: string
+ type: object
+ status:
+ description: AmbassadorInstallationStatus defines the observed state of
+ AmbassadorInstallation
+ properties:
+ conditions:
+ description: List of conditions the installation has experienced.
+ items:
+ description: AmbInsCondition defines an Ambassador installation condition,
+ as well as the last time there was a transition to this condition..
+ properties:
+ lastTransitionTime:
+ format: date-time
+ type: string
+ message:
+ type: string
+ reason:
+ type: string
+ status:
+ type: string
+ type:
+ type: string
+ required:
+ - status
+ - type
+ type: object
+ type: array
+ deployedRelease:
+ description: the currently deployed Helm chart
+ nullable: true
+ properties:
+ appVersion:
+ type: string
+ flavor:
+ type: string
+ manifest:
+ type: string
+ name:
+ type: string
+ version:
+ type: string
+ type: object
+ lastCheckTime:
+ description: Last time a successful update check was performed.
+ format: date-time
+ nullable: true
+ type: string
+ required:
+ - conditions
+ type: object
+ type: object
+ version: v2
+ versions:
+ - name: v2
+ served: true
+ storage: true
diff --git a/deploy/addons/ambassador/ambassador-operator.yaml b/deploy/addons/ambassador/ambassador-operator.yaml
new file mode 100644
index 000000000000..a6a6babe89e0
--- /dev/null
+++ b/deploy/addons/ambassador/ambassador-operator.yaml
@@ -0,0 +1,190 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: ambassador
+ labels:
+ addonmanager.kubernetes.io/mode: Reconcile
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: ambassador-operator
+ namespace: ambassador
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: ambassador-operator
+ namespace: ambassador
+rules:
+ - apiGroups:
+ - ""
+ resources:
+ - pods
+ - services
+ - services/finalizers
+ - endpoints
+ - persistentvolumeclaims
+ - events
+ - configmaps
+ - secrets
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+ - apiGroups:
+ - apps
+ resources:
+ - deployments
+ - daemonsets
+ - replicasets
+ - statefulsets
+ - customresourcedefinitions
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+ - apiGroups:
+ - monitoring.coreos.com
+ resources:
+ - servicemonitors
+ verbs:
+ - get
+ - create
+ - apiGroups:
+ - apps
+ resourceNames:
+ - ambassador-operator
+ resources:
+ - deployments/finalizers
+ verbs:
+ - update
+ - apiGroups:
+ - ""
+ resources:
+ - pods
+ verbs:
+ - get
+ - apiGroups:
+ - apps
+ resources:
+ - replicasets
+ - deployments
+ verbs:
+ - get
+ - apiGroups:
+ - getambassador.io
+ resources:
+ - '*'
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: ambassador-operator-cluster
+ namespace: ambassador
+rules:
+ - apiGroups: ['*']
+ resources: ['*']
+ verbs: ['*']
+ - nonResourceURLs: ['*']
+ verbs: ['*']
+---
+kind: RoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: ambassador-operator
+ namespace: ambassador
+subjects:
+ - kind: ServiceAccount
+ name: ambassador-operator
+roleRef:
+ kind: Role
+ name: ambassador-operator
+ apiGroup: rbac.authorization.k8s.io
+
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: ambassador-operator-cluster
+ namespace: ambassador
+subjects:
+ - kind: ServiceAccount
+ name: ambassador-operator
+ namespace: ambassador
+roleRef:
+ kind: ClusterRole
+ name: ambassador-operator-cluster
+ apiGroup: rbac.authorization.k8s.io
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: static-helm-values
+ namespace: ambassador
+data:
+ values.yaml: |+
+ deploymentTool: amb-oper-manifest
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: ambassador-operator
+ namespace: ambassador
+ labels:
+ getambassador.io/installer: operator
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ name: ambassador-operator
+ template:
+ metadata:
+ labels:
+ name: ambassador-operator
+ getambassador.io/installer: operator
+ spec:
+ serviceAccountName: ambassador-operator
+ containers:
+ - name: ambassador-operator
+ # Replace this with the built image name
+ image: quay.io/datawire/ambassador-operator:v1.2.3
+ command:
+ - ambassador-operator
+ imagePullPolicy: Always
+ env:
+ - name: WATCH_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: OPERATOR_NAME
+ value: "ambassador-operator"
+ volumeMounts:
+ - name: static-helm-values
+ mountPath: /tmp/helm
+ volumes:
+ - name: static-helm-values
+ configMap:
+ name: static-helm-values
diff --git a/deploy/addons/ambassador/ambassadorinstallation.yaml b/deploy/addons/ambassador/ambassadorinstallation.yaml
new file mode 100644
index 000000000000..befbf897f20e
--- /dev/null
+++ b/deploy/addons/ambassador/ambassadorinstallation.yaml
@@ -0,0 +1,9 @@
+apiVersion: getambassador.io/v2
+kind: AmbassadorInstallation
+metadata:
+ name: ambassador
+ namespace: ambassador
+spec:
+ installOSS: true
+ helmValues:
+ deploymentTool: amb-oper-minikube
diff --git a/pkg/addons/config.go b/pkg/addons/config.go
index 9faef8e484a9..66cf37aca348 100644
--- a/pkg/addons/config.go
+++ b/pkg/addons/config.go
@@ -134,4 +134,9 @@ var Addons = []*Addon{
set: SetBool,
callbacks: []setFn{enableOrDisableAddon},
},
+ {
+ name: "ambassador",
+ set: SetBool,
+ callbacks: []setFn{enableOrDisableAddon},
+ },
}
diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go
index 1d2191dd8231..3c2e1fcdedfe 100644
--- a/pkg/minikube/assets/addons.go
+++ b/pkg/minikube/assets/addons.go
@@ -369,6 +369,26 @@ var Addons = map[string]*Addon{
"0640",
true),
}, false, "metallb"),
+ "ambassador": NewAddon([]*BinAsset{
+ MustBinAsset(
+ "deploy/addons/ambassador/ambassador-operator-crds.yaml",
+ vmpath.GuestAddonsDir,
+ "ambassador-operator-crds.yaml",
+ "0640",
+ false),
+ MustBinAsset(
+ "deploy/addons/ambassador/ambassador-operator.yaml",
+ vmpath.GuestAddonsDir,
+ "ambassador-operator.yaml",
+ "0640",
+ false),
+ MustBinAsset(
+ "deploy/addons/ambassador/ambassadorinstallation.yaml",
+ vmpath.GuestAddonsDir,
+ "ambassadorinstallation.yaml.yaml",
+ "0640",
+ false),
+ }, false, "ambassador"),
}
// GenerateTemplateData generates template data for template assets
diff --git a/site/content/en/docs/tutorials/ambassador_ingress_controller.md b/site/content/en/docs/tutorials/ambassador_ingress_controller.md
new file mode 100644
index 000000000000..faf56fafee5e
--- /dev/null
+++ b/site/content/en/docs/tutorials/ambassador_ingress_controller.md
@@ -0,0 +1,131 @@
+---
+title: "Using Ambassador Ingress Controller"
+linkTitle: "Using Ambassador Ingress Controller"
+weight: 1
+date: 2020-05-14
+description: >
+ Using Ambassador Ingress Controller with Minikube
+---
+
+## Overview
+
+[Ambassador](https://getambassador.io/) allows access to Kubernetes services running inside Minikube. Ambassador can be
+configured via both, [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) resources and
+[Mapping](https://www.getambassador.io/docs/latest/topics/using/intro-mappings/) resources.
+
+## Prerequisites
+
+- Minikube version higher than v1.10.1
+- kubectl
+
+## Configuring Ambassador
+
+### Installing Ambassador
+
+Ambassador is available as a Minikube
+[addon]((https://github.com/kubernetes/minikube/tree/master/deploy/addons/ambassdor)). Install it by running -
+
+```shell script
+minikube addons enable ambassador
+```
+
+This will install Ambassador in the namespace `ambassador`.
+
+### Accessing Ambassador via `minikube tunnel`
+
+The service `ambassador` is of type `LoadBalancer`. To access this service, run a
+[Minikube tunnel](https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel) in a separate terminal.
+
+```shell script
+minikube tunnel
+```
+
+You can now access Ambassador at the external IP allotted to the `ambassador` service.
+Get the external IP with the following command:
+```shell script
+kubectl get service ambassador -n ambassador
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+ambassador LoadBalancer 10.104.86.124 10.104.86.124 80:31287/TCP,443:31934/TCP 77m
+```
+
+### Configuring via Ingress resource
+
+In this tutorial, we'll configure Ambassador via an Ingress resource. To configure via `IngressClass` resource, read
+this [post](https://blog.getambassador.io/new-kubernetes-1-18-extends-ingress-c34abdc2f064).
+
+First, let's create a Kubernetes deployment and service which we will talk to via Ambassador.
+
+```shell script
+kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4
+kubectl expose deployment hello-minikube --port=8080
+```
+
+This service `hello-minikube` is of type `ClusterIP` and is not accessible from outside the cluster.
+
+Now, create an Ingress resource which exposes this service at the path `/hello/`
+
+**Note:** The Ingress resource must have the annotation `kubernetes.io/ingress.class: ambassador` for Ambassador to
+pick it up.
+
+`hello-ingress.yaml`
+```yaml
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: ambassador
+ name: test-ingress
+spec:
+ rules:
+ - http:
+ paths:
+ - path: /hello/
+ backend:
+ serviceName: hello-minikube
+ servicePort: 8080
+```
+Run the command: `kubectl apply -f hello-ingress.yaml`
+
+That's it! You can now access your service via Ambassador:
+```shell script
+curl http://
+```
+
+**Note:** For more advanced Ingress configurations with Ambassador, like TLS termination and name-based virtual hosting,
+see Ambassador's [documentation](https://www.getambassador.io/docs/latest/topics/running/ingress-controller/).
+
+### Configuring via Mapping resource
+
+While Ambassador understands the Ingress spec, the Ingress spec does not leverage all of Ambassador's features. The
+[Mapping](https://www.getambassador.io/docs/latest/topics/using/intro-mappings/) resource is Ambassador's core resource
+that maps a target backend service to a given host or prefix.
+
+Let's create another Kubernetes deployment and service that we will expose via Ambassador -
+```shell script
+kubectl create deployment mapping-minikube --image=k8s.gcr.io/echoserver:1.4
+kubectl expose deployment mapping-minikube --port=8080
+```
+
+This service `mapping-minikube` is of type `ClusterIP` and is not accessible from outside the cluster.
+
+Now, let's create a mapping that exposes this service via Ambassador at the path `/hello-mapping/`
+
+`hello-mapping.yaml`
+```yaml
+apiVersion: getambassador.io/v2
+kind: Mapping
+metadata:
+ name: mapping-minikube
+spec:
+ prefix: /hello-mapping/
+ service: mapping-minikube.default:8080
+```
+Run the command: `kubectl apply -f hello-mapping.yaml`
+
+That's it! You can now access your service via Ambassador:
+```shell script
+curl http://
+```
+
+**Note:** Read more about mappings in Ambassador's
+[documentation](https://www.getambassador.io/docs/latest/topics/using/mappings/).
\ No newline at end of file