This guide provides information on how to use the IBM Cloud Operator to provision and bind IBM Cloud public instances.
To create an instance of an IBM public cloud service, create the following custom resource, service.yaml:
apiVersion: ibmcloud.ibm.com/v1
kind: Service
metadata:
name: myservice
spec:
plan: <PLAN>
serviceClass: <SERVICE_CLASS>To find the value for <SERVICE_CLASS>, you can list the names of all IBM public cloud
services with the command:
ibmcloud catalog service-marketplaceOnce you find the <SERVICE_CLASS> name, you can list the available plans to select
a <PLAN> with the command:
ibmcloud catalog service <SERVICE_CLASS> | grep planTo create the service:
kubectl apply -f service.yamlAfter creating a service, you can find its status with:
kubectl get services.ibmcloud
NAME STATUS AGE
myservice Online 12sWhen a service created by the operator is deleted out-of-band (e.g. via ibmcloud CLI or IBM Cloud UI) then the service is automatically re-created by the operator. This may take a few minutes because the IBM Cloud Operator runs at regular intervals, every few minutes.
Some combinations of service and plan require a global region. If this is not the case, the following
error message appears in the status of the service resource:
Failed: No deployment found for service plan <plan> at location <location>. Valid location(s) are: ["global"]Here's an example of how to set the region to global:
apiVersion: ibmcloud.ibm.com/v1
kind: Service
metadata:
name: mycos
spec:
plan: standard
serviceClass: cloud-object-storage
context:
region: globalMost services provision very rapidly and appear Online shortly after creation. However, some services can
take a while, such as 10 to 30mns. While they are provisioning the service resource will reflect
this state in its status. For example, a Cloudant resource will display inactive until it is fully provisioned.
Some services might even have say failed until they become Online.
During this time, the corresponding binding resource may also have a Failed status, because some services refuse
to create credentials while they are provisioning and return an error.
In these cases, everything becomes Online by simply waiting for a while. The service eventually becomes Online, and so does
the binding.
If a cloud service is already provisioned in your account, you can still create a service resource that is linked to that resource. This can be useful for example when the service has been created by an administrator, or the service is stateful and you need to maintain data associated with the service, or there are multiple clusters using the service, but only one is actively managing the service (creating and deleting instances) while the other clusters are only linking to that service.
To create a Service resource for an existing service instance in your account, you should use the name of the service
instance and the reserved plan name Alias. For example, if the service mytranslator already exists, you can
use the following custom resource to link it:
apiVersion: ibmcloud.ibm.com/v1
kind: Service
metadata:
name: mytranslator
namespace: default
spec:
plan: Alias
serviceClass: language-translatorThe following would also work:
apiVersion: ibmcloud.ibm.com/v1
kind: Service
metadata:
name: mytranslator-alias
namespace: default
spec:
plan: Alias
serviceClass: language-translator
externalName: mytranslatorFor CF-type services, the name is unique within a context (org & space), therefore the name is sufficient
to identify an existing service instance. Note that the serviceClassType must be set to CF for the service to be
recognized by the operator.
For IAM-type services, multiple service instances can have the same name. The example above will work only if there is one single instance of the service with that name. If multiple service instances with the same name exist, you must add an annotation to identify the particular instance you want to link to (in addition to specifying the name of the instance to link to).
To find the instance ID to use, you can list the current instances with the same name with the command:
ibmcloud resource service-instance <service-instance-name>for example:
ibmcloud resource service-instance mytranslator
Retrieving service instance mytranslator in resource group default under account Paolo Dettori's Account as dettori@us.ibm.com...
Multiple service instances found
OK
Name: mytranslator
ID: crn:v1:bluemix:public:language-translator:us-south:a/0b5a00334eaf9eb9339d2ab48f20d7f5:e641000a-9108-45fb-b2e6-ab7e52acc962::
GUID: e641000a-9108-45fb-b2e6-ab7e52acc962
Location: us-south
Service Name: language-translator
Service Plan Name: standard
Resource Group Name: default
State: active
Type: service_instance
Sub Type:
Created at: 2019-07-02T01:26:19Z
Updated at: 2019-07-02T01:26:19Z
Name: mytranslator
ID: crn:v1:bluemix:public:language-translator:us-south:a/0b5a00334eaf9eb9339d2ab48f20d7f5:aa7e9eba-e997-4e26-9aef-8d80f933625d::
GUID: aa7e9eba-e997-4e26-9aef-8d80f933625d
Location: us-south
Service Name: language-translator
Service Plan Name: lite
Resource Group Name: default
State: active
Type: service_instance
Sub Type:
Created at: 2019-07-02T02:13:15Z
Updated at: 2019-07-02T02:13:15Z In the example above, there are two instances with the same name. To identify
which one to use, you may look at the plan, which might be different, or the creation date.
Let's assume you want to use the first instance; then, simply copy the ID value into the
ibmcloud.ibm.com/instanceId annotation. The resource definition for this example is then:
apiVersion: ibmcloud.ibm.com/v1
kind: Service
metadata:
name: mytranslator
namespace: default
annotations:
ibmcloud.ibm.com/instanceId: "crn:v1:bluemix:public:language-translator:us-south:a/0b5a00334eaf9eb9339d2ab48f20d7f5:e641000a-9108-45fb-b2e6-ab7e52acc962::"
spec:
plan: Alias
serviceClass: language-translatorTo delete a service with name myservice, run:
kubectl delete service.ibmcloud myserviceThe operator uses kubernetes finalizers to manage the deletion of the custom resource. The operator first removes the service from IBM Cloud, then removes the finalizer, and at this point the custom resource should no longer be available in your cluster.\
kubectl get services.ibmcloud myservice
Error from server (NotFound): services.ibmcloud.ibm.com "myservice" not foundIf the resource being deleted is only linked to the service instance then deleting the resource will not delete the service instance.
You can bind to a service with name myservice using the following custom resource:
apiVersion: ibmcloud.ibm.com/v1
kind: Binding
metadata:
name: mybinding
spec:
serviceName: myserviceTo find the status of your binding, you can run the command:
kubectl get bindings.ibmcloud
NAME STATUS AGE
mybinding Online 25sA Binding generates a secret with the same name as the binding resource and
contains service credentials that can be consumed by your application.
kubectl get secrets
NAME TYPE DATA AGE
mybinding Opaque 6 102sWhen a binding and service are created in the same namespace, there is an ownership relationship. So when when the service is deleted, so is the binding. This relationship does not exist if they are not in the same namespace (since Kubernetes disallows it). In this case, the binding needs to be deleted manually and will not be deleted when the services is deleted.
Bindings can also be created by specifying Roles and ServiceIds. The following example shows a binding yaml with a specific Role:
apiVersion: ibmcloud.ibm.com/v1
kind: Binding
metadata:
name: binding-myes
spec:
serviceName: myes
role: EditorThe strings allowed for Roles depend on the service for which credentials are being created. When the role is not specified, the operator lists all the roles for that service types and picks the first one in that list, which defaults to Manager for most services.
ServiceIds can be specified by passing a parameter in the binding yaml:
apiVersion: ibmcloud.ibm.com/v1
kind: Binding
metadata:
name: binding-translator
spec:
serviceName: mytranslator
secretName: translator-secret
parameters:
- name: serviceid_crn
value: <crn:v1:bluemix:public:iam-identity::...>The serviceId crn can be obtained with the following command:
ibmcloud iam service-id <serviceId-name>When many bindings are needed on the same service, it is possible to link to the same set of credentials on the service instance, instead of creating new ones.
apiVersion: ibmcloud.ibm.com/v1
kind: Binding
metadata:
name: binding-translator-alias
annotations:
ibmcloud.ibm.com/keyId: <ID of key>
spec:
serviceName: mytranslator
alias: binding-translatorThe field alias indicates the name of the credentials to link to. This name must be unique, i.e. there cannot be other credentials on the same service instance with the same name. Note that binding secret keys replaces any spaces with underscores.
The yaml also requires an annotation ibmcloud.ibm.com/keyId for the ID of the credentials. This can be obtained by executing the following command and retrieving the ID field.
ibmcloud resource service-key <name-of-credentials>If the binding is deleted, this does not cause the deletion of the corresponding credentials.
To delete a binding with name mybinding, run:
kubectl delete binding.ibmcloud mybindingSimilarly to services, the operator uses finalizers to remove the custom resource only after the service credentials are removed. When a binding is deleted, the corresponding secret is also deleted.
In order to refresh credentials on a service, the user can simply delete and recreate a binding.