If there's one thing critical to any smooth-running Ops center, it's the need for automation. If we do things by hand, we introduce the risk of drift among our various components in production.
The following section shows some BASH scripts for deploying our microservices-based social media platform, a first step on the path towards automated deployment.
Assuming we've built everything with Gradle, let's kick things off by deploying our Spring Boot uber JARs to Cloud Foundry:
#!/usr/bin/env bash cf push learning-spring-boot-config-server -p config-server/build/libs/learning-spring-boot-config-server-0.0.1-SNAPSHOT.jar & cf push learning-spring-boot-eureka-server -p eureka-server/build/libs/learning-spring-boot-eureka-server-0.0.1-SNAPSHOT.jar & cf push learning-spring-boot -p chat/build/libs/learning-spring-boot-chat-0.0.1-SNAPSHOT.jar & cf push learning-spring-boot-comments -p comments/build/libs/learning-spring-boot-comments-0.0.1-SNAPSHOT.jar & cf push learning-spring-boot-images -p images/build/libs/learning-spring-boot-images-0.0.1-SNAPSHOT.jar & cf push learning-spring-boot-hystrix-dashboard -p hystrix-dashboard/build/libs/learning-spring-boot-hystrix-dashboard-0.0.1-SNAPSHOT.jar &
It can be described as follows:
- Each module is deployed using the CF CLI (https://github.com/cloudfoundry/cli), deploying with both a name and the JAR file
- Each command is backgrounded to speed up release
Let's get things underway and deploy! The console output shows us running our deployment script:
gturnquist$ ./deploy.sh Creating app learning-spring-boot-comments in org cosmos-refarch / space development as [email protected]... Creating app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Creating app learning-spring-boot-config-server in org cosmos-refarch / space development as [email protected]... Creating app learning-spring-boot-images in org cosmos-refarch / space development as [email protected]... Creating app learning-spring-boot-hystrix-dashboard in org cosmos-refarch / space development as [email protected]... Creating app learning-spring-boot-eureka-server in org cosmos-refarch / space development as [email protected]... ... Using route learning-spring-boot-config-server.cfapps.io Binding learning-spring-boot-config-server.cfapps.io to learning-spring-boot-config-server... Using route learning-spring-boot-comments.cfapps.io Binding learning-spring-boot-comments.cfapps.io to learning-spring-boot-comments... Using route learning-spring-boot-eureka-server.cfapps.io Binding learning-spring-boot-eureka-server.cfapps.io to learning-spring-boot-eureka-server... Using route learning-spring-boot-images.cfapps.io Binding learning-spring-boot-images.cfapps.io to learning-spring-boot-images... Using route learning-spring-boot.cfapps.io Binding learning-spring-boot.cfapps.io to learning-spring-boot... Using route learning-spring-boot-hystrix-dashboard.cfapps.io Binding learning-spring-boot-hystrix-dashboard.cfapps.io to learning-spring-boot-hystrix-dashboard... ... Uploading learning-spring-boot-config-server... Uploading learning-spring-boot-hystrix-dashboard... Uploading learning-spring-boot-comments... Uploading learning-spring-boot-eureka-server... Uploading learning-spring-boot-images... Uploading learning-spring-boot... ... Starting app learning-spring-boot-hystrix-dashboard in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-comments in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-images in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-eureka-server in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-config-server in org cosmos-refarch / space development as [email protected]... ... App started (the rest ommitted for brevity)
All components of our social media platform are now deployed to the cloud.
Be warned! This isn't enough. There are custom settings that must be applied after the bits are uploaded.
Let's start with the section that configures our Eureka server, as shown here:
#!/usr/bin/env bash cf set-env learning-spring-boot-eureka-server spring.cloud.config.uri https://learning-spring-boot-config-server.cfapps.io cf set-env learning-spring-boot-eureka-server spring.cloud.config.label production
Eureka needs to be configured with a Config Server URI and which label to fetch from GitHub, as done using cf set-env.
Next, we can look at the settings for the chat microservice:
cf set-env learning-spring-boot spring.cloud.config.uri https://learning-spring-boot-config-server.cfapps.io cf set-env learning-spring-boot spring.cloud.config.label production cf bind-service learning-spring-boot learning-spring-boot-mongodb cf set-env learning-spring-boot spring.data.mongodb.uri ${vcap.services.learning-spring-boot-mongodb.credentials.uri} cf bind-service learning-spring-boot learning-spring-boot-rabbitmq
The chat service needs a Config Server URI (with the GitHub label), a MongoDB service binding and URI setting, and a RabbitMQ service binding.
Next, we can look at the settings for the comments microservice, as shown here:
cf set-env learning-spring-boot-comments spring.cloud.config.uri https://learning-spring-boot-config-server.cfapps.io cf set-env learning-spring-boot-comments spring.cloud.config.label production cf bind-service learning-spring-boot-comments learning-spring-boot-mongodb cf set-env learning-spring-boot-comments spring.data.mongodb.uri ${vcap.services.learning-spring-boot-mongodb.credentials.uri} cf bind-service learning-spring-boot-comments learning-spring-boot-rabbitmq
The comments service needs a Config Server URI (with the GitHub label), a MongoDB service binding and URI setting, and a RabbitMQ service binding.
Next, we can look at the settings for the images microservice, as shown here:
cf set-env learning-spring-boot-images spring.cloud.config.uri https://learning-spring-boot-config-server.cfapps.io cf set-env learning-spring-boot-images spring.cloud.config.label production cf bind-service learning-spring-boot-images learning-spring-boot-mongodb cf set-env learning-spring-boot-images spring.data.mongodb.uri ${vcap.services.learning-spring-boot-mongodb.credentials.uri} cf bind-service learning-spring-boot-images learning-spring-boot-rabbitmq
The images service needs a Config Server URI (with the GitHub label), a MongoDB service binding and URI setting, and a RabbitMQ service binding.
With this in place, let's run the following configuration script:
gturnquist$ ./config.sh Setting env variable 'spring.cloud.config.uri' to 'https://learning-spring-boot-config-server.cfapps.io' for app learning-spring-boot-eureka-server in org cosmos-refarch / space development as [email protected]... Setting env variable 'spring.cloud.config.label' to 'production' for app learning-spring-boot-eureka-server in org cosmos-refarch / space development as [email protected]... Setting env variable 'spring.cloud.config.uri' to 'https://learning-spring-boot-config-server.cfapps.io' for app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Setting env variable 'spring.cloud.config.label' to 'production' for app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Binding service learning-spring-boot-mongodb to app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Setting env variable 'spring.data.mongodb.uri' to '${vcap.services.learning-spring-boot-mongodb.credentials.uri}' for app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Binding service learning-spring-boot-rabbitmq to app learning-spring-boot in org cosmos-refarch / space development as [email protected]... (the rest omitted for brevity)
Having applied these settings, we need to restart everything. To do so, we need the following script:
#!/usr/bin/env bash cf restart learning-spring-boot-config-server sleep 10 cf restart learning-spring-boot-eureka-server & cf restart learning-spring-boot & cf restart learning-spring-boot-comments & cf restart learning-spring-boot-images &
Why the delay after restarting the Config Server? It's important that it's given a chance to be up and operational before the other applications. So, let's run it as follows:
$ ./restart.sh Stopping app learning-spring-boot-config-server in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-config-server in org cosmos-refarch / space development as [email protected]... state since cpu memory disk details #0 running 2017-01-11 10:11:07 PM 207.4% 426.7M of 1G 146M of 1G Stopping app learning-spring-boot-images in org cosmos-refarch / space development as [email protected]... Stopping app learning-spring-boot-eureka-server in org cosmos-refarch / space development as [email protected]... Stopping app learning-spring-boot in org cosmos-refarch / space development as [email protected]... Stopping app learning-spring-boot-comments in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-eureka-server in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-images in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot-comments in org cosmos-refarch / space development as [email protected]... Starting app learning-spring-boot in org cosmos-refarch / space development as [email protected]... App started (the rest ommitted for brevity)
We can easily check their status like this:
$ cf apps Getting apps in org cosmos-refarch / space development as [email protected]... OK name requested state instances memory disk urls learning-spring-boot started 1/1 1G 1G learning-spring-boot.cfapps.io learning-spring-boot-comments started 1/1 1G 1G learning-spring-boot-comments.cfapps.io learning-spring-boot-config-server started 1/1 1G 1G learning-spring-boot-config-server.cfapps.io learning-spring-boot-eureka-server started 1/1 1G 1G learning-spring-boot-eureka-server.cfapps.io learning-spring-boot-hystrix-dashboard started 1/1 1G 1G learning-spring-boot-hystrix-dashboard.cfapps.io learning-spring-boot-images started 1/1 1G 1G learning-spring-boot-images.cfapps.io
Let's take a peek. We can do so by visiting http://learning-spring-boot.cfapps.io (in an incognito tab to ensure a fresh session):
We will see the all too familiar login page.
If we log in as greg/turnquist, delete the default images and load up our favorites from earlier, we can expect to see this:
Our favorite chat channel is at the bottom of the page, as shown in the following screenshot:
For extra maintenance, the following script can be used to delete all the apps (but not the related AMQP and MongoDB services):
#!/usr/bin/env bash cf delete -f learning-spring-boot-config-server & cf delete -f learning-spring-boot-eureka-server & cf delete -f learning-spring-boot & cf delete -f learning-spring-boot-comments & cf delete -f learning-spring-boot-images & cf delete -f learning-spring-boot-hystrix-dashboard &
Using the CF CLI, all the services are deleted in a background job.