How to configure Pulumi using YAML Config Files
Published: 2024-06-16 18:56:15

How to configure Pulumi using YAML Config Files
 
When working with Pulumi the other day, I noticed that there are some crucial steps in the documentation which were lacking.

For example when you have to use the YAML file to configure your environment.

I even asked in the Slack forum, the official channel of Pulumi Engineers, and I dropped a question, which led to more confusion. After some time I found out the way they had done it. And his answer were the one who helped me. This is taken from one of the engineers working at Pulumi.


I had to search through the big internet to find what I was looking for, I stumbled upon some blog posts, and decided to write my own.

Fraser Water was the guy who helped me reach my goal, and a fun fact is that he is one of the authors on the Project Level Configuration page, which he referred me to in the slack discussion. As well as many others, he have been working directly on the Pulumi team.


When working with Pulumi, you can orchestrate your infrastructure with code, and as shown in the last Post.

However, when you want to orchestrate your environment, you don’t want to use the command line tool to insert variables.

For example, you can use the command line tool, to set a variable called Azure Location to NorwayEast. As an example


pulumi config set AzureLocation NorwayEast
This is fine, when you want to just set a password, but when you have a lot of configuration you would like to swap out, it would be cumbersome to only use the terminal. 

That is where the Pulumi Yaml files comes into play.

This can be as advanced as you like it, and it supports nesting.

For example, you can set up your Yaml file like this.

```

 Core-Api-Ioc:az-env:
    default:
      tenant:id: xcx2
      subscription:id: 7dxx60dfbax3x
      resource-group:name: rg-youresourcegroup-dev
      location: norwayeast 
```
Then you can get access to the YAML file in the code this way

var azEnv = config.RequireObject<JsonElement>("az-env");

TenantId = azEnv.GetProperty("tenant:id").GetString() ?? string.Empty;

SubscriptionId = azEnv.GetProperty("subscription:id").GetString() ?? string.Empty;

Location = azEnv.GetProperty("location").GetString() ?? string.Empty;

ResourceGroupName = azEnv.GetProperty("resource-group:name").GetString() ?? string.Empty;

 What I have done is to create a class called AzureEnv

You could do this directly in the CoreDevStack.cs file if you'd like, but doing it this way I found out that it helped to clean up my code. 

```
using System.Text.Json;
using Config = Pulumi.Config;
 
namespace Core.Api.Iac.IocConfiguration.Azure;
 
public class AzureEnv
{
    public AzureEnv(Config config)
    {
        var azEnv = config.RequireObject<JsonElement>("az-env");
        TenantId = azEnv.GetProperty("tenant:id").GetString() ?? string.Empty;
        SubscriptionId = azEnv.GetProperty("subscription:id").GetString() ?? string.Empty;
        Location = azEnv.GetProperty("location").GetString() ?? string.Empty;
        ResourceGroupName = azEnv.GetProperty("resource-group:name").GetString() ?? string.Empty;
    }
 
    internal string SubscriptionId { get; }
    internal string ResourceGroupName { get; }
    internal string TenantId { get; }
    internal string Location { get; }
}
```
Here is an example of nesting the code

```
Core-Api-Ioc:dbsmydatabase:
  default:
    servername: dbsncoredev
    version: 12.0
    location: westeurope
    security-properties:
      admin-login: yourinformation
      administrator-type: ActiveDirectory
      ad-login: sa-group-dba-dev
      principal-type: Group
      sid: e7343xx53796
      tenant-id: 8c34534534xx0a002
Core-Api-Ioc:dbsmydatabase:

 default:

 servername: dbsncoredev

 version: 12.0

 location: westeurope

 security-properties:

 admin-login: yourinformation

 administrator-type: ActiveDirectory

 ad-login: sa-group-dba-dev

 principal-type: Group

 sid: e7343xx53796

 tenant-id: 8c34534534xx0a002

Then we can get access to it, by doing this.

 Again I have configured a class



using System.Text.Json;
using Core.Api.Iac.IocConfiguration.Azure.Data.Sql.Common;
using Core.Api.Iac.IocConfiguration.Azure.Data.Sql.Databases;
using Config = Pulumi.Config;
 
namespace Core.Api.Iac.IocConfiguration.Azure.Data.Sql.Server;
 
public class AzNovoSidDevSql : CommonDb
{
    public AzNovoSidDevSql(Config config)
    {
        var azDbsNCoreDev = config.RequireObject<JsonElement>("dbsmydatabase");
        ServerName = azDbsNCoreDev.GetProperty("servername").GetString() ?? string.Empty;
        Version = azDbsNCoreDev.GetProperty("version").GetDouble();
        Location = azDbsNCoreDev.GetProperty("location").GetString() ?? string.Empty;
        var securityProperties = azDbsNCoreDev.GetProperty("security-properties");
        SecurityProperties.AdminLogin = securityProperties.GetProperty("admin-login").GetString() ?? string.Empty;
        SecurityProperties.AdministratorType = securityProperties.GetProperty("administrator-type").GetString() ?? string.Empty;
        SecurityProperties.AzLogin = securityProperties.GetProperty("ad-login").GetString() ?? string.Empty;
        SecurityProperties.PrincipalType = securityProperties.GetProperty("principal-type").GetString() ?? string.Empty;
        SecurityProperties.Sid = securityProperties.GetProperty("sid").GetString() ?? string.Empty;
        SecurityProperties.TenantId = securityProperties.GetProperty("tenant-id").GetString() ?? string.Empty;
    }
    public SecurityProperties SecurityProperties { get; } = new();
}
```
And in the CoreDevStack.cs file I call it in the constructor


```

var azDbsMyDatabase = new AzNovoSidDevSql(config);

```
Hopefully this helped you a bit as well, if you have any questions, please let me know, I try to answer as much as I can.