Working with Cloud Foundary – Basic Tutorials

Section 1 – The CLI

The CLI, or Command Line Interface, is the tool you will use to interact with Cloud Foundry. The CLI runs in a terminal window and makes REST calls to the Cloud Foundry API. The CLI has been preinstalled in the terminal window.

You can verify this by checking the version:

$ cf version

Help
The CLI is a self-documenting tool. For example, you can run:

cf help to see a list of the most commonly used commands
$ cf help 
cf help -a to see a list of all the available commands
$ cf help -a

cf <command> --help to see details on using a specific command

Section 2 – Logging in

When using a Cloud Foundry instance, you first need to login. 

$ cf auth admin "$CF_ADMIN_PASSWORD"
$ cf create-org devopsschool-org
$ cf create-space -o devopsschool-org devopsschool-space
$ cf target -o devopsschool-org -s devopsschool-space
$ cf target

Now that you are logged in, you are ready to deploy and application.

Section 3 – Pushing an app

In Cloud Foundry, deploying an app is achieved via a cf push. There is nothing special about the app you will be deploying. It is just a simple compiled go application written for training purposes.

The application is packaged as a zip file and is already in your current directory. Along with the application is a file called a manifest, which provides directives to Cloud Foundry on what to do with the app.

You can view the manifest used to deploy your application with cat manifest.yml. Let’s look at the directives in the

manifest.yml:

  • name: first-push The name of the application in Cloud Foundry. This name should be a descriptive name for use by humans and can anything you want.
  • instances: 1 Specifies how many instances of the application to create
  • memory: 32M Specifies how much memory the container running each instance is allocated
  • disk_quota: 256M Specifies how much disk the container running each instance is allocated
  • path: ./sample-app.zip Specifies the location of the application bits, in our case a zip file
  • routes: Specifies the route or routes where your app should be accessible
  • route: first-push-12345.kubecf1.rscale.dev We generated this route to ensure yours is unique (it will be different than this value)
  • buildpacks: The buildpacks used to containerize your application

binary_buildpack In this case, we only need the binary buildpack as this is compiled go code.

You can deploy the application using: cf push

The push command looks for a file named manifest.yml and uses it to deploy the application.

Section 4 – Checking your work

The push should take about a minute. If everything is successful, you should see output for your running application similar to:

name:              first-push
requested state:   started
routes:            first-push-12345.kubecf.rscale.dev
last uploaded:     Sat 07 Mar 11:47:05 MDT 2020
stack:             cflinuxfs3
buildpacks:        binary

type:            web
instances:       1/1
memory usage:    32M
start command:   ./bin/sample-app
     state     since                  cpu    memory     disk      details
#0   running   2020-03-07T17:46:53Z   0.0%   0 of 32M   0 of 256M

The application has a user interface that shows some details about the application. You can copy the url of your application from your terminal window (not from the example above) labeled as a routes and open it in another tab in your browser. Be sure to use a new tab and not this one.

Section 5 – Wait, what just happened?

In short, you deployed an app using a single command. It would have looked the same regardless of the language in which the app was written. The CLI on your machine uploaded the app bits to Cloud Foundry and also provided some information about what should happen.

Cloud Foundry took your app bits and used a buildpack to create a container image with your app plus any necessary runtime dependencies. The resulting image was then used to run your application in a container. Once your app was running, Cloud Foundry began to automatically route traffic to it (hence your ability to access it in a browser).

Cloud Foundry has been running apps in containers since long before Kubernetes or Docker existed. If believe that you must run your apps in Kubernetes, we have good news: you just did. Both the Cloud Foundry instance you are using and your application are running on Kubernetes.

And what didn’t happen?

You didn’t build an image with a tool like Docker (though Cloud Foundry supports Docker, too). You didn’t install any runtimes or manipulate any file systems. You didn’t manually provision any resources like compute and storage. You didn’t create and deploy a load balancer or reserve any ports. You didn’t update routing tables or do any health checks. You just typed cf push. Pretty cool, right?

Now that we have an app running, let’s provision a database for it to use.

Section 6 – Provisioning a Database

Your app is now running, but it doesn’t have a database. If you view your application in a browser, you will see the database is missing. Let’s add a database.

“But wait… I don’t want to learn how to install, configure and manage MySQL, MariaDB, Postgres, etc.”

No problem. The Cloud Foundry marketplace is a collection of services that can be provisioned on demand. The marketplace in different Cloud Foundry instances may differ.

  • You can see the marketplace by running: $ cf marketplace
    Inside the marketplace, you will find a MySQL database service that you can provision on demand.
  • We can create a new instance called first-push-db using $ cf create-service mysql free first-push-db

Let’s dissect the above command:

  • The mysql is the name of the offering as listed in the marketplace.
  • The free is the name of the plan, or service tier, to create.
  • first-push-db is a descriptive name for this database instance as referred to in Cloud Foundry. Again, this name is used by humans, and can be whatever you want.
  • NOTE: The application was built for training purposes only and does not store any actual data.

Section 7 – Provisioning a Database: Checking Your Work

You should be able to see a new service instance using $ cf services

Getting services in org cloudfoundry-training / space development as sgreenberg@rscale.io…
OK

name service plan bound apps last operation
first-push-db mysql free create succeeded

Okay, so what happened now?

Behind each service in the marketplace is a service broker (a broker can provide multiple services). Service brokers encapsulate the complexity of provisioning and interacting with different services using a standard API, the Open Service Broker API. The marketplace is populated when Cloud Foundry invokes the broker to find out what services it is offering. Those offerings include one or more plans which detail service levels or tiers of service. When you issued the create-service command, Cloud Foundry made a call to the broker to provision a database instance according to the plan.

And what didn’t happen?

You didn’t learn how to deploy, configure and manage the database. You didn’t figure out service levels or routing. You simply used a standard API to provision a new instance.

Now that we have our instance, let’s bind it to our app.

Section 8 – Binding a Database

Now that you have a database instance, you need to tell your application about the instance so the app can use it. In Open Service Broker API terms this is called binding.

Bind the service instance you created to your application: $ cf bind-service first-push first-push-db

Now restart your application so that it picks up the change: $ cf restart first-push

Checking Your Work
If you re-run cf services you should see your app now bound to your database.

name service plan bound apps last operation
first-push-db mysql free first-push create succeeded
You can also refresh your app in the browser and should see it is now using the database.

Okay, what happened?

When you issued the bind-service command, Cloud Foundry again made a call to a service broker. This time, the broker created credentials for your application and granted the necessary permissions to access the database. These credentials were returned to Cloud Foundry, which passed them to your application through an environment variable. This is why you needed to restart the app – so that it would pick up the new environment variable values containing the credentials. At this point, the app connects to the database using the credentials. The broker is not involved in this communication and your app treats it like any other database.

And what didn’t happen?

You didn’t learn to create new database users, set credentials and grant access to resources. You also didn’t change any configuration files in the application since it is written to read config from the environment (the number III 12 factor app best practice). You simply issued a single command and restarted the app.

Great! Now that the app is using an external database, let’s scale it.

Section 9 – Scaling the Application

Now that you have the application data moved to an external service, we can safely scale our application up to more than one instance. After all, running a single instance of something is a recipe for an outage.

Scale your app to two instances: $ cf scale first-push -i 2


Checking your work
You can see the status of your app by running $ cf app first-push

name: first-push
requested state: started
routes: first-push-12345.kubecf.rscale.dev
last uploaded: Sat 07 Mar 11:47:05 MDT 2020
stack: cflinuxfs3
buildpacks: go

type: web
instances: 2/2
memory usage: 64M
state since cpu memory disk details
0 running 2020-03-07T18:30:42Z 0.2% 10.2M of 32M 14.6M of 256M
1 running 2020-03-07T18:34:46Z 0.3% 9.5M of 32M 14.6M of 256M

If you refresh the app in your browser multiple times, you will see the App Instance Index change. Cloud Foundry is load balancing your requests across both instances.

What happened?

Remember that image Cloud Foundry created when you pushed the app? Cloud Foundry grabbed a cached version of it and started a new container. When the app became available, Cloud Foundry started routing traffic to it. With multiple instances running, Cloud Foundry load balances traffic across them.

And what didn’t happen?

Just like on a push, no creating resources. No updating routing tables. No updating load balancers. Just cf scale.

Now that we have two instances running, let’s crash one and see what happens.

Section 10 – Application Resiliency

By performing cf scale in the last exercise, you asked Cloud Foundry to ensure you have two instances of the app running. Behind the scenes, Cloud Foundry is ensuring this is so. Let’s test it.

To see this happen, we can watch the logs. We haven’t talked about logs yet, but running cf logs will tail the logs for all of your application instances.

In the terminal window, tail the logs: $ cf logs first-push

You will see output similar to:

Retrieving logs for app first-push in org Katacoda / space 12345 as 12345…
This command doesn’t run and exit. It keeps running, so it will not return to a command prompt. That is what we want.

Killing an App Instance
The application has a /kill endpoint that will crash the instance programatically.

When you are ready, you can stop tailing the logs by hitting CTRL-C in the terminal window.

Pretty cool. So what happened?


Cloud Foundry is constantly monitoring the actual count of the running application instances and comparing that number to the desired count. If it finds an issue, Cloud Foundry will correct it (in our case, by creating a new instance). And just like during scaling, when the new instance becomes available Cloud Foundry routes traffic to it.

And what didn’t happen?

A lot. All apps get this level of care from Cloud Foundry. You don’t have to do anything other than use Cloud Foundry.

Section 11 – Application Resiliency

Delete the app and the route: $ cf delete -f -r first-push

Delete the service instance: $ cf delete-service -f first-push-db

Section 12 – Congratulations! You just:

  • Deployed an application to Cloud Foundry (and Kubernetes) using cf push.
  • Created a service instance from the marketplace (cf marketplace and cf create-service) and bound it to your application using cf bind-service.
  • Scaled your application using cf scale.
  • Observed the application resiliency capability of Cloud Foundry by killing an instance.
  • Cleaned it all up.
Rajesh Kumar
Follow me