Cloud Foundry Provider
The Cloud Foundry provider enables the standard Cloud Foundry environment variables (VCAP_APPLICATION
, VCAP_SERVICES
, and CF_*
) to be parsed and accessed as configuration data within a .NET application.
Cloud Foundry creates and uses these environment variables to communicate an application's environment and configuration to the application code running inside a container. More specifically, the values found in VCAP_APPLICATION
provide information about the application's resource limits, routes (URIs), and version number, among other things. The VCAP_SERVICES
environment variable provides information about the external services (Databases, Caches, and so on) to which the application is bound, along with details on how to contact those services.
You can read more information on the Cloud Foundry environment variables at the Cloud Foundry docs website.
The Steeltoe Cloud Foundry provider supports the following .NET application types:
- ASP.NET (MVC, WebForms, WebAPI, WCF)
- ASP.NET Core
- Console apps (.NET Framework and .NET Core)
Usage
You should have a good understanding of how the .NET Configuration services work before starting to use this provider.
In order to use the Steeltoe Cloud Foundry provider you need to do the following:
- Add a NuGet package reference to your project.
- Add the provider to the Configuration Builder.
- Configure Cloud Foundry options classes by binding configuration data to the classes.
- Inject and use the Cloud Foundry Options to access Cloud Foundry configuration data.
NOTE: Most of the example code in the following sections is based on using Steeltoe in an ASP.NET Core application. If you are developing an ASP.NET 4.x application or a Console based app, see the other samples for example code you can use.
Add NuGet Reference
To use the provider, you need to add a reference to the appropriate Steeltoe Cloud Foundry NuGet based on the type of the application you are building and what Dependency Injector you have chosen, if any. The following table describes the available packages:
App Type | Package | Description |
---|---|---|
Console/ASP.NET 4.x | Steeltoe.Extensions.Configuration.CloudFoundryBase |
Base functionality. No dependency injection. |
ASP.NET Core | Steeltoe.Extensions.Configuration.CloudFoundryCore |
Includes base. Adds ASP.NET Core dependency injection. |
ASP.NET 4.x with Autofac | Steeltoe.Extensions.Configuration.CloudFoundryAutofac |
Includes base. Adds Autofac dependency injection. |
To add this type of NuGet to your project, add a PackageReference
resembling the following:
<ItemGroup>
...
<PackageReference Include="Steeltoe.Extensions.Configuration.CloudFoundryCore" Version="2.5.2" />
...
</ItemGroup>
Add Configuration Provider
In order to parse the Cloud Foundry environment variables and make them available in the application's configuration, you need to add the Cloud Foundry configuration provider to the ConfigurationBuilder
.
The following example shows how to do so:
using Steeltoe.Extensions.Configuration;
...
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
// Add VCAP_* configuration data
.AddCloudFoundry();
Configuration = builder.Build();
...
When developing a .NET Core application, you can do the same thing by using the AddCloudFoundry()
extension method for either the IWebHostBuilder
or Generic IHostBuilder
. The following example shows how to do so:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseCloudFoundryHosting()
// Add VCAP_* configuration data
.AddCloudFoundry()
.UseStartup<Startup>()
.Build();
}
Access Configuration Data
Once the configuration has been built, the values from the VCAP_APPLICATION
and VCAP_SERVICES
environment variables have been added to the application's configuration data and become available under keys prefixed with vcap:application
and vcap:services
respectively.
You can access the values from the VCAP_APPLICATION
environment variable settings directly from the configuration as follows:
var config = builder.Build();
var appName = config["vcap:application:application_name"]
var instanceId = config["vcap:application:instance_id"]
...
A list of all VCAP_APPLICATION
keys is available in the VCAP_APPLICATION topic of the Cloud Foundry documentation.
You can also directly access the values from the VCAP_SERVICES
environment variable. For example, to access the information about the first instance of a bound Cloud Foundry service with a name of service-name
, you could code the following:
var config = builder.Build();
var name = config["vcap:services:service-name:0:name"]
var uri = config["vcap:services:service-name:0:credentials:uri"]
...
A list of all VCAP_SERVICES
keys is available in the VCAP_SERVICES topic of the Cloud Foundry documentation.
NOTE: This provider uses the built-in .NET JSON Configuration Parser when parsing the JSON provided in the
VCAP_*
environment variables. As a result, you can expect the exact same key names and behavior as you see when parsing JSON configuration files (such asappsettings.json
) in your application.
Access Configuration Data as Options
ConfigureCloudFoundryOptions()
Alternatively, instead of accessing the Cloud Foundry configuration data directly from the configuration, you can use the .NET Options framework together with Dependency Injection.
The Cloud Foundry provider includes two additional classes, CloudFoundryApplicationOptions
and CloudFoundryServicesOptions
. Both can be configured through the Options framework to hold the parsed VCAP_*
data by using the Options Configure()
feature.
To use it in an ASP.NET Core application, add the the following to the ConfigureServices()
method in the Startup
class:
using Steeltoe.Extensions.Configuration.CloudFoundry;
public void ConfigureServices(IServiceCollection services)
{
// Setup Options framework with DI
services.AddOptions();
// Add Steeltoe Cloud Foundry Options to service container
services.ConfigureCloudFoundryOptions(Configuration);
}
The ConfigureCloudFoundryOptions(Configuration)
method call uses the Options framework to bind the vcap:application
configuration values to an instance of CloudFoundryApplicationOptions
and binds the vcap:services
values to an instance of CloudFoundryServicesOptions
.
Both of these method calls also add these objects to the service container as IOptions
.
Once this is done, you can access these configuration objects in the Controllers or Views of an application by using normal Dependency Injection.
The following example controller shows how to do so:
using Steeltoe.Extensions.Configuration.CloudFoundry;
public class HomeController : Controller
{
public HomeController(IOptions<CloudFoundryApplicationOptions> appOptions,
IOptions<CloudFoundryServicesOptions> serviceOptions)
{
AppOptions = appOptions.Value;
ServiceOptions = serviceOptions.Value;
}
CloudFoundryApplicationOptions AppOptions { get; private set; }
CloudFoundryServicesOptions ServiceOptions { get; private set; }
// GET: /<controller>/
public IActionResult Index()
{
ViewData["AppName"] = AppOptions.ApplicationName;
ViewData["AppId"] = AppOptions.ApplicationId;
ViewData["URI-0"] = AppOptions.ApplicationUris[0];
ViewData[ServiceOptions.ServicesList[0].Label] = ServiceOptions.ServicesList[0].Name;
ViewData["client_id"]= ServiceOptions.ServicesList[0].Credentials["client_id"].Value;
ViewData["client_secret"]= ServiceOptions.ServicesList[0].Credentials["client_secret"].Value;
ViewData["uri"]= ServiceOptions.ServicesList[0].Credentials["uri"].Value;
return View();
}
}
ConfigureCloudFoundryService
As an alternative to using CloudFoundryServicesOptions
to access Cloud Foundry service data you can also use ConfigureCloudFoundryService<TOption>()
or ConfigureCloudFoundryServices<TOption>()
to easily gain access to service data.
These methods allow you to define an Option class which represents a particular type of Cloud Foundry service binding and then use either method to select that data from VCAP_SERVICES
and bind the data to it.
To do this, you first need to create a Options class that derives from AbstractServiceOptions
. That class must match the data provided in VCAP_SERVICES
.
Here is an example that illustrates how to do this for a MySql service binding on PCF:
using Steeltoe.Extensions.Configuration.CloudFoundry;
public class MySqlServiceOption : AbstractServiceOptions
{
public MySqlServiceOption() { }
public MySqlCredentials Credentials { get; set; }
}
public class MySqlCredentials
{
public string Hostname { get; set; }
public int Port { get; set; }
public string Name { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Uri { get; set; }
public string JdbcUrl { get; set; }
}
Next in your Startup
class you can use either ConfigureCloudFoundryService<TOption>()
or ConfigureCloudFoundryServices<TOption>()
to bind the service data from VCAP_SERVICES
to your TOption
. There are multiple ways to do this depending on your needs.
You can use ConfigureCloudFoundryService<TOption>()
method to select a specific Cloud Foundry service binding from VCAP_SERVICES
by specifying a service name. Or you can use ConfigureCloudFoundryServices<TOption>()
to bind to all services of a particular type by specifying a Cloud Foundry service label.
Here are some examples:
using Steeltoe.Extensions.Configuration.CloudFoundry;
public void ConfigureServices(IServiceCollection services)
{
// Setup Options framework with DI
services.AddOptions();
// Bind VCAP_SERVICES data for mySql2 service instance to MySqlServiceOption
services.ConfigureCloudFoundryService<MySqlServiceOption>(Configuration, "mySql2");
// Bind VCAP_SERVICES data for all p-mysql service instances to MySqlServiceOption
services.ConfigureCloudFoundryServices<MySqlServiceOption>(Configuration, "p-mysql");
}
As you can see all of this is built using the Microsoft provided Options framework. As a result we are able to leverage the named
Options feature Microsoft has implemented in options binding, and configure each TOption
with a name equal to the Cloud Foundry service name found in VCAP_SERVICES
.
What this means is within a controller you can inject the IOptionsSnapshot<MySqlServiceOption>
or IOptionsMonitor<MySqlServiceOption>
as you normally would and then access the Option by name. (for example: specific Cloud Foundry service binding instance).
Here is an example:
public class HomeController : Controller
{
private IOptionsSnapshot<MySqlServiceOption> _mySqlOptions;
private MySqlServiceOption MySqlOptions
{
get
{
return _mySqlOptions.Get("mySql2");
}
}
public HomeController(IOptionsSnapshot<MySqlServiceOption> mySqlOptions)
{
_mySqlOptions = mySqlOptions;
}