astonishing-monitor-96741
06/29/2021, 12:50 PMbrave-planet-10645
06/29/2021, 12:53 PMisSecret
method you can use. Let me just grab the linkastonishing-monitor-96741
06/29/2021, 12:54 PMbrave-planet-10645
06/29/2021, 12:56 PM.isSecretAsync()
for .netastonishing-monitor-96741
06/29/2021, 12:57 PMbored-oyster-3147
06/29/2021, 1:57 PMOutput.IsSecretAsync(...)
astonishing-monitor-96741
06/29/2021, 3:44 PMJsonElement data = config.RequireObject<JsonElement>("Settings");
Looping through the JsonElements I want, if I Console.WriteLine, it knows its a secret and outputs accordingly.
Console.WriteLine(JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }));
{
"Region": "us-east-1",
"SecretKey": "[secret]",
"User": "service-worker"
}
But I'm struggling to use the Output.IsSecretAsync passing in a string or JsonElement.
I tried creating a new Pulumi.Output.Create with the value, but still returns False.
var val = Pulumi.Output.Create(item.Value);
var isSecret = Task.Run(async () => await Output.IsSecretAsync(val));
var isSecret2 = await Output.IsSecretAsync(val);
Console.WriteLine($"IsSecret: {isSecret.Result}");
Console.WriteLine($"IsSecret: {isSecret2}");
I'm noobing something up here but I've gone cross eyed.bored-oyster-3147
06/29/2021, 3:45 PMOutput.IsSecretAsync
is correct for this because this is coming from config so isn't an output?astonishing-monitor-96741
06/29/2021, 3:45 PMbored-oyster-3147
06/29/2021, 3:47 PMconfig.RequireObject<T>
and config.RequireSecretObject<T>
?astonishing-monitor-96741
06/29/2021, 3:48 PMconfig.RequireObject<JsonElement>("Settings");
config:
Application:Settings:
AppSettings:
AllowedLoginAttempts: 4
CaptchaInfo:
CaptchaKey: FAKEKEY
CaptchaSecret:
secure: REMOVED
bored-oyster-3147
06/29/2021, 3:49 PMJsonElement
I think. You might need to manually check if the property has the { "secret": { ... } }
shape inside the JsonElement
secure
propertyastonishing-monitor-96741
06/29/2021, 3:50 PMbored-oyster-3147
06/29/2021, 3:51 PMRequireObject
which pulumi is not using your passphrase to deserialize so it just has the plaintext [secret]
for those valuesastonishing-monitor-96741
06/29/2021, 3:51 PMbored-oyster-3147
06/29/2021, 3:52 PMastonishing-monitor-96741
06/29/2021, 3:54 PMName = name,
Value = item.Value.ToString()
JsonElement.Value.ToString()bored-oyster-3147
06/29/2021, 3:54 PMastonishing-monitor-96741
06/29/2021, 3:54 PMbored-oyster-3147
06/29/2021, 4:04 PMJsonElement.Value.ToString()
is doing any kind of decryption but I guess that's not super relevant to your issue.
To get back to your issue, it looks like internally the Deployment
instance keeps a hash set of all of the fully qualified configuration keys that are secrets and uses this method to check that collection. It doesn't appear that this is exposed any where that I have been able to find, so maybe we could open an issue to expose something like that on the Config
objectastonishing-monitor-96741
06/29/2021, 4:10 PMbored-oyster-3147
06/29/2021, 4:12 PMastonishing-monitor-96741
06/29/2021, 4:12 PMbrave-planet-10645
06/29/2021, 4:12 PMastonishing-monitor-96741
06/29/2021, 4:22 PMbrave-planet-10645
06/29/2021, 5:09 PMSystem.Text.Json
so Pulumi is just converting the secret config value and passing through as [secret]
astonishing-monitor-96741
06/29/2021, 5:35 PM[secret]
like you mention if I write it out.
Below is the full code I'm using to pull it out of the config, flatten the hierarchy, and write it to console. Later on I loop through the settings collection to add each key/value to AWS parameter store. Everything works perfect, other than I'd like to recognize the secrets and add them to parameter store as SecureString.
public AppConfig()
{
var config = new Pulumi.Config("Application");
JsonElement data = config.RequireObject<JsonElement>("Settings");
SettingsCollection = GetFlat(data.ToString());
Console.WriteLine("*************************************");
Console.WriteLine(JsonSerializer.Serialize(SettingsCollection, new JsonSerializerOptions { WriteIndented = true }));
Console.WriteLine("*************************************");
}
public static Dictionary<string, JsonElement> GetFlat(string? json)
{
if (json == null) return new Dictionary<string, JsonElement>();
IEnumerable<(string Path, JsonProperty P)> GetLeaves(string? path, JsonProperty p)
=> p.Value.ValueKind != JsonValueKind.Object
? new[] { (Path: path == null ? p.Name : path + "/" + p.Name, p) }
: p.Value.EnumerateObject().SelectMany(child => GetLeaves(path == null ? p.Name : path + "/" + p.Name, child));
using (JsonDocument document = JsonDocument.Parse(json))
return document.RootElement.EnumerateObject()
.SelectMany(p => GetLeaves(null, p))
.ToDictionary(k => k.Path, v => v.P.Value.Clone()); //Clone so that we can use the values outside of using
}
Example config with pulumi CLI created structured secret
config:
Application:Settings:
AppSettings:
AllowedLoginAttempts: 4
CaptchaInfo:
CaptchaKey: FAKEKEYasdfasdfasdf
CaptchaSecret:
secure: REMOVEDojiijfjio32ji23jfj0f3093j923j09
Code for the looping and ssm creation:
foreach (var item in appConfig.SettingsCollection)
{
string name = $"/{prefix}/{item.Key}";
new Ssm.Parameter(name, new Ssm.ParameterArgs
{
Name = name,
Value = item.Value.ToString() ?? "[ERROR] config entry null",
Type = "String",
DataType = "text"
});
}
brave-planet-10645
06/29/2021, 6:18 PMconfig.RequireSecretObject()
bored-oyster-3147
06/29/2021, 6:23 PM[secret]
especially after seeing his GetFlat(...)
function since he's just getting that nested JsonElement
and doing JsonElement.Value.ToString()
So it seems like he just needs to do RequireSecretObject<JsonElement>()
but not so that his pulumi program functions (cause it does currently) just so that the secrets are decrypted early for the purpose of his string usageRequireSecretObject<JsonElement>
he still has no way of knowing which of those nested elements are actually secrets so that he can conditionally use SecureString
in his SSM parameter resourceastonishing-monitor-96741
06/29/2021, 6:25 PMbrave-planet-10645
06/29/2021, 6:54 PMastonishing-monitor-96741
06/29/2021, 6:56 PMbrave-planet-10645
06/29/2021, 8:34 PM