I have always been a fan of event-driven automation, the idea where you can automatically trigger a workflow or an operation based on a specific event. In the consumer world, the most popular example is the If This, Then That (IFTTT) service, which I use on a regular basis to automate the sharing of new articles from virtuallyGhetto to different Social Media channels.
For the Enterprise, this is also not a new idea and many folks including myself have been doing this for years in vSphere using vCenter Server Alarms. In fact, one example I still reference on a regular basis is from 2012 where you automatically apply a set of vSphere Security Hardening configurations to a Virtual Machine when a new VM Create Event is published by vCenter.
There are countless more examples of this concept beyond VMware but the general idea is to be able to subscribe to specific events and then automatically do something when a given event occurs. When Github Actions (Beta) was announced last year, I was really interested as I think this could open the door for a ton of interesting possibilities, especially from a VMware perspective around Continuous Integration/Development (CI/CD). I quickly registered for the Beta but did not get access until the start of this year. If you want to know what Github Actions can do, check out some of these demos that have been built by various folks from the community. The really exciting thing about Github Actions is that you can literally execute any workflow as long as you can containerized your business logic within a Docker Container. This means, you can use any language or tool that you are familiar with and make this work with Github Actions, pretty powerful stuff!
It was only recently while working on a personal project, which I hope will make its way to VMworld, that I finally got a chance to dig into Github Actions. I noticed in many of the online Github Action examples, that it included ways to deploy applications and containers to a Public Cloud but there was nothing that I found related to VMware. I figured, this would be a good learning opopournity for myself and I could even learn how to build my own Actions which can be useful for others to use or extend further.
Below is the high level workflow which consists of checking-in some code into a Github repo (git push) which will then trigger a Github Action that will automatically deploy a specific VM Template from a vSphere Content Library running on VMware Cloud on AWS (VMC). The VM is configured with a startup script that will automatically pull down the latest version of that same Github repo, which is a basic Go Web Application and then deploys it for testing. In my VMC environment, I have also configured a NAT rule which makes the application accessible over the Internet but this is not required for folks who do not have this need or only require internal testing.
The sample Go Application can be found at https://github.com/lamw/demo-go-webapp which I used from Martin Ombura Jr. and his excellent example post here. The application is very basic, it just displays an image running on port 8080 and you can specify a URL argument (e.g. http://<server>:8080/?name=William) which is then rendered in a welcome message as shown in the screenshot below.
The initial repo has a background image of a rocky beach, let's now configure the Github repo to add a Github Action to automatically perform the above workflow when a new push occurs.
Step 1 - Navigate to your Github repo (can be public or private) and if you have Github Actions enabled, you should see a new Actions tab. Click on the "Create a new workflow" button to begin. You have the option of using the UI Wizard, which I recommend for first timers but you can also use the editor if you already know what the input will be consuming a specific Github Action. Using the Wizard, you will go ahead and give the Action a name
Step 2 - Name your workflow and specify when it should run (e.g. push, fork, etc) and then drag the blue connector to the box below to associate with a Github Action. Once you do this, you will be able to select from a number of Github Actions found in the Github Marketplace or specify one from the community.
To use my Deploy VM from vSphere Content Library Github Action, you just need to specify the following: docker://lamw/deploy-vm-from-content-library which is simply a Docker Image that I have built using govc to perform the VM deployment. Click on the "Use" button to proceed to the next step.
Step 3 - Next, we need to define our secrets and environmental variables, which is how we will pass information to the Docker Container and connect to either a vSphere or a VMC environment to deploy our VM. For sensitive information such as credentials, we will want to use Secrets which will encrypt the data immediately. Click on "Create a new secret" and specify the label as GOVC_PASSWORD and then the account password you wish to use to connect to your vCenter Server. For the remainder user input, these can be standard environmental variables and below is the example of the input:
GOVC_URL=https://<vcenter>/sdk
GOVC_USERNAME=*protected email*
GOVC_DATACENTER=SDDC-Datacenter
GOVC_NETWORK=sddc-cgw-network-1
GOVC_DATASTORE=WorkloadDatastore
GOVC_FOLDER=Workloads
GOVC_RESOURCE_POOL=Compute-ResourcePool
LIBRARY_NAME=Customer[0]
LIBRARY_TEMPLATE=PhotonOS-Template
VM_NAME=Validate-New-Background-Image
Step 4 - Once you are done filling out all the required variables, go ahead and click on the "Start Commit" button at the top which will then commit the Github Action to your Github repo. One downside to using git "push" to trigger the Github Action is that when you add/update the Github Action workflow, this itself also causes a push and will then start the Github Action.
As you can see from the screenshot below, after configuring the Github Action, it automatically runs and this is also a nice way to verify that the Github Action is working correctly.
Once you get more familiar with Github Actions, you can skip the UI entirely and simply add .github/main.workflow which contains the Github Action configuration and then you can simply add this with the specific settings for other repos.
Okay, let's now go through a real workflow where the Github Action will trigger based on some changes to our Github repo. In my example, I am simply replacing the background image from a rocky beach to sandy beach. Once I commit the update with a git "push", we should see the Action trigger and it will move into a waiting to run state and then execute as shown in the screenshot below.
If the Github Action was successful, you will see a link to the log which you can click on. Here, we can see all the stdout output from the Docker Container including output that I have also echo'd out for information purposes.
A faster way to confirm that everything worked as expected is by taking a look at our VMC environment using the vSphere UI. We can see the Github Action did indeed trigger and a new VM has been deployed from our vSphere Content Library that we had specified in our configuration.
If we now access the web application, we can see the background has changed from the old image to the new one and we have verified that our application is working as expected!
Although this was a very simple example, hopefully it demonstrates what you can do with Github Actions and vSphere (which includes VMC) in how you develop, build and test your applications. In a follow-up post, I will go into more details on how to create your own Github Actions, especially as it pertains VMware-specific tools and SDKs.
Stephane says
Hi William,
Thanks for all the great content you share with the community!
Can you please explain me one point I don't understand ? How do you create connectivity between GitHub and VMC vCenter ? Is VMC vCenter exposed on the Internet?
thanks
William Lam says
This is all done within the VMC Firewall for providing connectivity in/out of your SDDC. You'll need to enable connectivity from Github <-> Github Runner VM for control plane activities and you'll need connectivity from Github Runner VM <-> VMC vCenter for actual workload deployment/etc. Hope that helps