How to get VCAP_SERVICES environment variables WITHOUT binding to an application? - ibm-cloud

Frequently, I'm create standalone services in Bluemix. For example, Analytics for Apache Hadoop, Cloudant and DashDB.
I don't need an application to work with these services, but it seems I have to bind to an application just to get access to the VCAP_SERVICES environment variables with urls, usernames, passwords, etc.
Question: How to get VCAP_SERVICES environment variables WITHOUT binding to an application?

For many services, you will have to bind them to an app in order to get the VCAP_SERVICES credentials.
There is a service key capability which some services are starting to adopt which allows you to create and access credentials without binding to an app. Using the cf command line tool, the commands below are available to use if a service supports them:
SERVICES:
create-service-key, csk Create key for a service instance
service-keys, sk List keys for a service instance
service-key Show service key info
delete-service-key, dsk Delete a service key
The CloudFoundry docs at https://docs.cloudfoundry.org/devguide/services/service-keys.html provide more detail.
In the Bluemix UI, you would see a 'Service Credentials' option in the panel when viewing a service dashboard when a service supports this capability. Selecting this option allows you to see credentials that have been created as well as an "Add Credentials" button to create new ones.

Related

How to use service account to authenticate Cloud Run to Firestore

I'm looking for a way to connect Cloud Run to Firestore without using a service account access key. I have a key set up for my local dev environment to access Firestore. I know you can access Firestore from the account running Cloud Run containers, but haven't been able to find any documentation on how to do this.
The most I could find is using a Workforce Identity Federation but that seems to be focused on connecting external services which isn't my goal.
Edit, forgot to mention I'm using nodejs and am not using firebase, just firestore
Every service in Cloud Run has a service account assigned (default Compute Engine service account), but you can create you own service account and assign it (Recommended), you don't need to download a key.
Cloud Run console
In the IAM section look for datastore permissions instead of Firestore permissions, because Firestore is the 'evolution' of datastore.
Follows the doc for more info: https://cloud.google.com/run/docs/configuring/service-accounts

injected db credentials change when I deploy new app version to cloud

I deploy a web app to a local cloudfoundry environment. As a database service for my DEV environment I have chosen a Marketplace service google-cloudsql-postgres with the plan postgres-db-f1-micro. Using the Web UI I created an instance with the name myapp-test-database and mentioned it in the CF Manifest:
applications:
- name: myapp-test
services:
- myapp-test-database
At first, all is fine. I can even redeploy the existing artifact. However, when I build a new version of my app and push it to CF, the injected credentials are updated and the app can no longer access the tables:
PSQLException: ERROR: permission denied for table
The tables are still there, but they're owned by the previous user. They were automatically created by the ORM in the public schema.
While the -OLD application still exists I can retrieve the old username/password from the CF Web UI or $VCAP_SERVICES and drop the tables.
Is this all because of Rolling App Deployments? But then there should be a lot of complaints.
If you are strictly doing a cf push (or restart/restage), the broker isn't involved (Cloud Controller doesn't talk to it), and service credentials won't change.
The only action through cf commands that can modify your credentials is doing an unbind followed by a bind. Many, but not all, service brokers will throw away credentials on unbind and provide new, unique credentials for a bind. This is often desirable so that you can rotate credentials if credentials are compromised.
Where this can be a problem is if you have custom scripts or cf cli plugins to implement rolling deployments. Most tools like this will use two separate application instances, which means you'll have two separate bindings and two separate sets of credentials.
If you must have one set of credentials you can use a service key to work around this. Service keys are like bindings but not associated with an application in CloudFoundry.
The downside of the service key is that it's not automatically exposed to your application, like a binding, through $VCAP_SERVICES. To workaround this, you can pass the service key creds into a user-provided service and then bind that to your application, or you can pass them into your application through other environment variables, like DB_URL.
The other option is to switch away from using scripts and cf cli plugins for blue/green deployment and to use the support that is now built into Cloud Foundry. With cf cli version 7+, cf push has a --strategy option which can be set to rolling to perform a rolling deployment. This does not create multiple application instances and so there would only ever exist one service binding and one set of credentials.
Request a static username using the extra bind parameter "username":
cf bind-service my-app-test-CANDIDATE myapp-test-database -c "{\"username\":\"myuser\"}"
With cf7+ it's possible to add parameters to the manifest:
applications:
- name: myapp-test
services:
- name: myapp-test-database
parameters: { "username": "myuser" }
https://docs.cloudfoundry.org/devguide/services/application-binding.html#arbitrary-params-binding
Note: Arbitrary parameters are not supported in app manifests in cf CLI v6.x. Arbitrary parameters are supported in app manifests in cf CLI v7.0 and later.
However, I can't find the new syntax here: https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html#services-block . The syntax I use comes from some other SO question.

IBM Cloud: How to bind Db2 Warehouse to Code Engine app?

I have an existing instance of Db2 Warehouse on Cloud which is deployed to an org and space. Now, I would like to bind that service to an app for deployment with IBM Cloud Code Engine.
ibmcloud ce application bind --name henriks-app --service-instance myDb2
myDb2 does not exist as IAM resource because it is a CF resource. How would I bind the two together? It seems that I would need to create some form of custom wrapper.
The best way to manually connect services to your Code Engine application is to add service credentials to a Code Engine secret, and then attach that secret to your application using environment variables or volume mounting.
While you're correct that Db2 Warehouse isn't a typical IAM-Enabled service type, based on the IBM Cloud Db2 Warehouse docs, it's possible to create a client connection with Db2 Warehouse using an IAM Service ID & API Key.
Here's how I'd "bind" the Db2 instance to a Code Engine app:
Create a new service ID from the IAM Service IDs page
Under "Assign Access" > "Access service ID additional access" > "IAM Service", you'll find "Db2 Warehouse" as an option, and you can configure exact permissions from there (e.g. which instance(s) to grant permissions to, which roles, etc)
Finish the configuration by clicking "Assign access"
Using the CLI, log in to your account and generate a new API Key, e.g. ibmcloud iam service-api-key-create mydb2key SERVICE_ID_NAME --output JSON > mydb2.json where SERVICE_ID_NAME is the name of the service ID created in Step 1
Target your Code Engine project, then create a new secret using the API Key JSON, e.g. ibmcloud ce secret create --name mydb2 --from-file MYDB2=mydb2.json
Attach the secret to your application as an environment variable, e.g. ibmcloud ce app update --name myapp --env-from-secret mydb2
After the app update goes through, your application will have access to an environment variable named MYDB2, which will have the value of a JSON object string containing your API Key.
You'll find more information about creating secrets and using secrets with applications in the Code Engine docs.

How do you change the automatically created password?

I've got a Cloudant service that is associated with my Bluemix app. When it was setup, a username/password combo was created automatically. I accidentally shared the credentials (it is just a demo), so now I want to change the password. As far as I can see, there is no way to actually change the password - either on the dashboard or the site itself. Where is this done?
There is no UI to change your credentials. You can contact support. I recommend you create a new instance, use the Replication tab in the Cloudant console to migrate your database, and then delete the old one.
Service credentials are usually created by binding the service instance to an application. Not every service broker works this way, but most do. Simply unbinding the service:
cf unbind-service myapp myservice-instance
And then rebinding:
cf bind-service myapp myservice-instance
Should result in new credentials being generated to the same service instance. Since you can bind a service to multiple applications, each application generally gets different credentials (depending on the service broker implementation).

Can I use a service bound to apps in one Bluemix region across other Bluemix regions?

There are multiple regions in Bluemix. I have a service instance bound to an application in one region and I want to use that service instance in other Bluemix regions.
I've not found a clear intuitive way to do this. Is there a supported method?
Thanks!
There is no explicit mechanic for making a service instance available across regions from the Bluemix dashboard, but it can be done with a user-provided service instance.
Starting from the region where I have my service instance running and bound to my application I needed to grab the credentials and connection parameters from the VCAP_SERVICES environment variable for service instance.
I did this by displaying the Overview page in the Bluemix dashboard by clicking the title of my application.
Next, in the left navigation pane, I click Environment Variables to get at the value of VCAP_SERVICES. Environment variable details are displayed on the right pane and from there I am able to capture the JSON content for the service instance.
Now I go to the region(s) where I want to make use of the service instance in the first region. I go to the Bluemix menu bar and click the Region icon, then select the new or target region.
User provided services are an excellent vehicle for accessing resources (databases, locally developed programs, ...) that may not exist in Bluemix. So long as you have the credentials needed to get to these resources across the internet, a user-provided service can be built in Bluemix to liase with these external entities. I learned about user-provided services at Creating a user-provided service instance.
I use the credentials and connection parameters I captured from the VCAP_SERVICES environment variable and create a user-provided service instance in the new or target region.
Last step is to bind my new user-provided service instance to an app in the new region by using the following command:
cf bind-service myapp user-provided_service_instance