Azure Bicep ( key vault secret passing as a parameter to local variable) - azure

I am new to Azure Bicep.I am trying to use the key vault secret name and value for the virtual machine (Window) credential. But I am facing a problem with passing the name and value of the key vault as a parameter to a local variable. Anyone who can guide me regarding this matter?
#description('Password for the Virtual Machine.')
#secure()
param adminPassword string = keyVault.getSecret()

You can't use the getSecret() function in the main.bicep file (i.e. as a defaultValue) - you can only use that in a module within a bicep file. #Deep has a link for that...
If you want to pass the secret to main.bicep you need to use a parameter reference in a parameter file, see: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-tutorial-use-key-vault#edit-the-parameters-file

Related

Best Practice for BICEP to Ignore Overwriting Existing KeyVault Secrets

I have the following GUID that is generated in my BICEP module and used as a value in a KeyVault secret
param keyVaultName string
param apiKey string = newGuid()
resource apikey_secret 'Microsoft.KeyVault/vaults/secrets#2021-11-01-preview' = {
name: '${keyVaultName}/ApiKey'
properties:{
value: apiKey
attributes:{
enabled: true
}
}
}
Every time I run the BICEP files this GUID is generated and replaces the previous value. My preference is for this to only be generated on the first run and then ignored if it exits on any subsequent run.
I came across this solution which uses tags to track existing secrets and then conditionals within the BICEP file checking to see if the tag exists.
I feel like there should be a more elegant solution than having to manage tags in addition to secrets but cannot find anything in the docs so far.
There isn't any way to do a "deploy only if it doesn't exist" in bicep/ARM - ARM is declarative so will always seek the goal specified in the template.
Another option you can consider is to use a deterministic guid that way it won't change, but someone with knowledge of how the function works could "determine" the secret value, e.g.
#secure
param apiKey string = guid(apikey_secret.id)
Nit - in your code snippet the param is not secure so someone with permission to the deployment at scope can retrieve the value.

How to read connection string from key vault for Service Bus?

Here is how I instantiate the client in my Configure method:
services.AddSingleton<ServiceBusClient>(x => new ServiceBusClient(configuration.GetSection("ServiceBus:ConnectionString").Value, serviceBusClientOptions));
And this how my appsettings looks like:
{
"ServiceBus:ConnectionString": "#Microsoft.KeyVault(VaultName=MyVaultName;SecretName=MySecretName)"
}
However, I am getting the following exception:
The connection string used for an Service Bus client must specify the Service Bus namespace host and either a Shared Access Key (both the name and value) OR a Shared Access Signature to be valid. (Parameter 'connectionString'
What am I missing here?
Have you created a managed identity for you application and added access policies such that your app can GET this secret value from key vault?
Check out the official documentaion for this here : https://learn.microsoft.com/en-us/azure/app-service/app-service-key-vault-references
Also on a side note, have you tried directly adding the secret value as the appsetting value instead of referencing it from KV and see if that worked? (if yes then definitely its a permissions issue and NOT a problem with your C# app code.

ADF error when reusing parameter in replace function

I am parameterizing a Linked Service (SQL server) in ADF, but have trouble reusing parameters for different service properties as Dynamic Content.
I have created more parameters for the SQL Server properties:
ServerName
Environment
DatabaseName
DBUserName
A Key Vault is used to store sensitive information for the properties, where the Secret names are created like like "POC-USER-MYDOMAIN-MYUSER".
The DBUserName parameter for the Linked Service contains a Windows Login like "MyDomain\MyUser". I use the DBUserName parameter for property "User name" and for the password stored in Key Vault.
Property "User name" has this dynamic content "#{linkedService().DBUserName}", and the Key Vault Secret name has this dynamic content "#{linkedService().Environment}-USER-#{replace(linkedService().DBUserName, '', '-')}".
Linked service
When execute "Test connection" I use these parameters:
Parameters
And "Test connection" returns this error:
Error
I can get it working, if I create a new parameter named "DBUserNameCopy", copy value from "DBUserName". Then change either property "User name" or property "Key Vault Secret name" dynamic content to use the new parameter. And execute "Test connection" with:
DoubleParameters
So the two properties dynamic content is working correct, but only if they don't share one parameter.
I tried different things to avoid this error, but ended up with the conclusion: You can not use same parameter in more properties, if you use the replace function (I don't know if it's related to all functions).
Anyone know how to get this to work?
I tried this scenario, and it seems that you cannot use the same linked service parameter in two dynamic expressions. In your case you used the DBUsername twice, once in the user name dynamic expression and the second in constructing the key vault secret name. Aside from your workaround, to create a parameter with a different name, I would manipulate the value you pass to the key vault secret name parameter outside the linked service, do this in the data set that references the linked service, in the data set definition, include the dynamic expression that prepares the parameter value.

Terraform - Access SSM Parameter Store Value Access

I would like some help / guidance on how to securely access SSM Parameter store for the (decrypted) value on an existing secureString for use in other terraform resources?
e.g we have a github access token stored in SSM for CI - I need to pass this value to the GitHub provider to enable webhooks for codepipeline.
The SSM Parameter is not something managed from terraform, but its decrypted value can be used.
Is this insecure given the value would end up in the state file? What is the best practice for this type of use case?
Many thanks!
You can use the data source to reference an already existing resource:
data "aws_ssm_parameter" "foo" {
name = "foo"
}
one of the properties of the data source is value, which contains the actual value of the parameter. You can use this elsewhere in your terraform code:
data.aws_ssm_parameter.foo.value

How do I update value of my Secret created in Azure Key Vault using .Net SDK

I added a connection string in my KeyVault Secret. I wanted to update the same using .Net SDK but not able to find any method that will allow me to do so.
I tried using UpdateSecretAsync() but this method doesn't accept Secret Value.
Can someone please point me to correct method.
Use the SetSecretAsync method. If the secretName doesn't exists it will create it. If it does exist it will replace it.
// Code to generate a new secret
var newSecret = "<the new secret>"
// Update the secret in the key vault
client.SetSecretAsync(vault, secretName, newSecret);

Resources