Access string stored in secret manager from CDK - node.js

I am storing the Codestar connection string for Bitbucket in Secret manager. How can I retrieve it in the CDK app:
I am trying with:
// Get Bitbucket Connection String
const bitbucketConnectionString = Secret.fromSecretCompleteArn(this, "bitbucketConnectionString", "arn:aws:secretsmanager:us-west-2:1000000000:secret:BitbucketCloudConnection-abcdef0");
// SourceAction
const sourceAction = new BitBucketSourceAction({
actionName: 'BitbucketSource',
owner: 'abc',
repo: repoName,
output: sourceOutputArtifact,
connectionArn: bitbucketConnectionString,
})
bitbucketConnectionString is not a string though.
How do I access the secret value which is actually a connectionString stored in Secret Manager.
What is the right way to replace region and accountId with Pseudo variables in the connection string;
arn:aws:secretsmanager:us-west-2:1000000000:secret:BitbucketCloudConnection-abcdef0

The account and region reference can be set up on the basis of the environment variables you have. You should be able to use a this.account or this.region to reference the current stack/constructs environment details.

Related

Is it possible to create a secret_id to use it in an approle automatically without the help of an administrator or kubernetes when using vault?

Recently searching the internet I found a good alternative to manage the secrets of my application created in node js with the help of hashicorp vault. I have investigated how it works and among the possible ways that this tool has to enter I found approle, which I consider an adequate form of authentication through my application. This form of authentication requires a role_id and a secret_id. The latter, as I see in the examples of the official vault page, needs an entity for its creation and then passes it to the application and in this way the application can receive the token to enter the vault. Currently I have this code in node js that receives a token wrapped with the secret_id to achieve access to the secrets with the role of the application:
//get the wrap token from passed in parameter
var wrap_token = process.argv[2];
if(!wrap_token){
console.error("No wrap token, enter token as argument");
process.exit();
}
var options = {
apiVersion: 'v1', // default
endpoint: 'http://127.0.0.1:8200',
token: wrap_token //wrap token
};
console.log("Token being used " + process.argv[2]);
// get new instance of the client
var vault = require("node-vault")(options);
//role that the app is using
const roleId = '27f8905d-ec50-26ec-b2da-69dacf44b5b8';
//using the wrap token to unwrap and get the secret
vault.unwrap().then((result) => {
var secretId = result.data.secret_id;
console.log("Your secret id is " + result.data.secret_id);
//login with approleLogin
vault.approleLogin({ role_id: roleId, secret_id: secretId }).then((login_result) => {
var client_token = login_result.auth.client_token;
console.log("Using client token to login " + client_token);
var client_options = {
apiVersion: 'v1', // default
endpoint: 'http://127.0.0.1:8200',
token: client_token //client token
};
var client_vault = require("node-vault")(client_options);
client_vault.read('secret/weatherapp/config').then((read_result) => {
console.log(read_result);
});
});
}).catch(console.error);
The problem is that I plan to upload the application in the cloud using docker and the idea is that the process of obtaining the secrets is automatic so I would like to know if when creating a token that lasts long enough that you only have the possibility of obtaining the secret_id of a role and saving it as environment variable is appropriate in this case or if there is any other alternative that can help me in automating this case.
Note: I don't plan to deploy in aws in this case.

Pulumi: query pulumi stack value if not given

Here is my use case:
I have a blob resource that is created only if a file (artifcat from my CI server) is present on my build machine.
Now, I may have to run pulumi on my local machine where the file does not exist. But I don't want to delete the blob resource. The blob is still present on Azure.
if (fs.existsSync(fullFileName)) {
// On the build server, I update the blob with the new artifact
const blob = new azure.storage.Blob("myblob-b", {
name: fileName,
source: fullFileName,
resourceGroupName: resourceGroup.name,
storageAccountName: storageAccount.name,
storageContainerName: zipDeployContainer.name,
type: "block"
})
} else {
// On my local machine, the artifact does not exists but I want to keep it
const stackRef = new pulumi.StackReference(`${organization}/${projectName}/${stackName}`);
const srblob = stackRef.getOutput("zipblob");
// How do I tell pulumi keep the resource from the stack reference
}
export const zipblob = blob;
Ok, i'm not smart enough for this, people on pulumi slack helped me out. Basically you can use StackReference. Specifically the getOutput method.

How to find Cosmos DB Endpoint and where to get lib directory referenced in this code?

Here is sample code for querying a CosmosDB
Here is the part of the code I am concerned with replicating so I can make queries on my own database.
const cosmos = require("../../lib/");
const CosmosClient = cosmos.CosmosClient;
const config = require("../Shared/config");
const databaseId = config.names.database;
const containerId = config.names.container;
const endpoint = config.connection.endpoint;
const masterKey = config.connection.authKey;
// Establish a new instance of the CosmosClient to be used throughout this demo
const client = new CosmosClient({ endpoint, auth: { masterKey } });
I'm not sure what my endpoint should be in order to query the database. My queries are Read-only (doesn't need to be strictly read only, but for what I'm doing, read-only is all that's needed), but I don't know what is in ../../lib/ that the cosmos variable is set equal to, and I don't know what the endpoint variable should contain (obviously some sort of endpoint, but which one). The ../../lib/ directory doesn't appear to be in the github repo.
The connection information can be found in the Keys section of the Azure portal.
The endpoint is the value in the URI section.
In case of the CosmosDB emulator, the default URI is https://localhost:8081.

Authenticate to multiple Azure services using Service Principle (.net Core)

I need to get access to Key Vault and Service Bus from code, using a Service Principle for authentication.
I can use the following code to access Service Bus, which works as expected - when I enable to Service Principle in the Access Policies I can pull the list of topics:
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(APPID, APPSECRET, TENANTID, AzureEnvironment.AzureGlobalCloud);
var serviceBusManager = ServiceBusManager.Authenticate(credentials, SUBSCRIPTIONID);
var serviceBusNamespace = serviceBusManager.Namespaces.List().SingleOrDefault(n => n.Name == "SERVICEBUSNAMESPACE");
var topics = serviceBusNamespace.Topics.ListAsync().GetAwaiter().GetResult();
However, I also need to get some information from Key Vault and I was trying to establish a common way to authenticate.
METHOD 1
Similar to the above, I tried this code to access KeyVault:
var credentials = SdkContext.AzureCredentialsFactory.FromServicePrincipal(APPID, APPSECRET, TENANTID, AzureEnvironment.AzureGlobalCloud);
var kvManager = new KeyVaultClient(credentials);
var secret = kvManager.GetSecretAsync("https://VAULTNAMESPACE.vault.azure.net", "SECRETNAME").GetAwaiter().GetResult().Value;
I get the the following error:
Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: 'Operation
returned an invalid status code 'Unauthorized''
METHOD 2
This code does work for Key Vault however (showing I have correct permissions):
string GetSecret()
{
var client = new KeyVaultClient(GetAccessToken);
var secret = client.GetSecretAsync("https://VAULTNAMESPACE.vault.azure.net", "SECRETNAME").GetAwaiter().GetResult();
return secret;
}
private static async Task<string> GetAccessToken(string authority, string resource, string scope)
{
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
var credential = new ClientCredential(appId, appSecret);
var tokenResult = await context.AcquireTokenAsync("https://vault.azure.net", credential);
return tokenResult.AccessToken;
}
But, again, it's a very KeyVault specific way to Authenticate and I was hoping to establish a common mechanism using SdkContext.AzureCredentialsFactory. Any reason why I'd be getting an Unauthorized exception with the code above connecting to Key Vault? (all is set up correctly in Azure).
Thanks for any tips!
When you use SdkContext.AzureCredentialsFactory.FromServicePrincipal to authenticate, it will use https://management.azure.com/ as its Resource Uri.
While Azure Key Vault has its own authorization system and its Resource Uri is https://vault.azure.net, so you may get the Unauthorized error message.
So, you could use Method2 to get access to Azure Key Vault with right Resource Uri.
For more details, you could refer to this article.

Pull data from azure keyvault with node

I'm trying to pull data from Azure KeyVault with Node. I installed azure-keyvault with npm and read some of the guides that Microsoft released (e.g. https://www.npmjs.com/package/azure-keyvault) but I can't get data to output. Just for testing purposes I'd like to do something like View contents of Secret in Azure KeyVault with node.
var KeyVault = require('azure-keyvault');
var util = require('util');
var Crypto = require('crypto');
var AuthenticationContext = require('adal-node').AuthenticationContext;
var clientId = 'xxx';
var clientSecret = 'xxx';
var vaultUri = 'xxx';
I can't find an API with a list of commands that I can do with the keyvault var, how do I pull data from keyvault?
Edit: so I have var KeyVault = require('azure-keyvault');
and the KeyVault variable can be used as an object with methods listed in here: http://azure.github.io/azure-sdk-for-node/azure-keyvault/latest/?
Here is the 'azure-keyvault' library docs: http://azure.github.io/azure-sdk-for-node/azure-keyvault/latest/
I can't find an API with a list of commands that I can do with the keyvault var
you use the "keyvault var" to create a keyvault client. in the link above, see the side menu for a list of all commands.
how do I pull data from keyvault?
For example, you can use the KeyVaultClient.getSecrets function: http://azure.github.io/azure-sdk-for-node/azure-keyvault/latest/KeyVaultClient.html#getSecrets
The package azure-keyvault has been deprecated in favor of the new packages to deal with Keyvault keys, secrets and certificates separately. For your scenario, you can use the new #azure/keyvault-secrets package.
The readme at for #azure/keyvault-secrets has a variety of code snippets you can refer to. You can refer to the entire sample set for secrets too.
To read secrets from azure key vault you can use npm library read-azure-secrets, in which you will need to pass client ID, client secret, and vault URI. It will return all secrets from your key vault.
Example -
const secretClient = require('read-azure-secrets');
async function loadKeyVaultValues() {
let applicationID = '';
let applicationSecret = '';
let vaultURL = 'https://<your-key-vault-name>.vault.azure.net/';
let secrets = await secretClient.getSecrets(applicationID, applicationSecret, vaultURL);
secrets.forEach(secret => {
console.log(secret);
});
}
loadKeyVaultValues();

Resources