Where is my database password in Altostra project? - amazon-web-services

I’ve created a project in Altostra. I've created a Lambda function in the vscode extension and connected it to an RDS instance. The password is apparently auto-generated and “accessible to any lambda”, but where do I access it?

When you connect lambda to the database resource, you will have connection details provided for you into lambda's environment variable.
Here you have DB_SECRET_RDS02, representing the "secret" you need.
Then, in the Lambda code, you will have access to the variable through process.env
const aws = require('aws-sdk')
// retrieving host and port
const [host, port] = process.env.DB_RDS02.split(':')
// retrieving secret from SecretManager
const secretManager = new aws.SecretsManager()
const secret = await secretManager.getSecretValue({
SecretId: process.env.DB_SECRET_RDS02
}).promise()
// retrieving data from secret
const { username, password } = JSON.parse(secret.SecretString)

Related

How to add api-key to google secret-manager

With Terraform GCP provider 4.30.0, I can now create an google maps api key and restrict it.
resource "google_apikeys_key" "maps-api-key" {
provider = google-beta
name = "maps-api-key"
display_name = "google-maps-api-key"
project = local.project_id
restrictions {
api_targets {
service = "static-maps-backend.googleapis.com"
}
api_targets {
service = "maps-backend.googleapis.com"
}
api_targets {
service = "places-backend.googleapis.com"
}
browser_key_restrictions {
allowed_referrers = [
"https://${local.project_id}.ey.r.appspot.com/*", # raw url to the app engine service
"*.example.com/*" # Custom DNS name to access to the app
]
}
}
}
The key is created and appears in the console as expected and I can see the API_KEY value.
When I deploy my app, I want it to read the API_KEY string.
My node.js app already reads secrets from secret manager, so I want to add it as a secret.
Another approach could be for the node client library to read the API credential directly, instead of using secret-manager, but I haven't found a way to do that.
I can't work out how to read the key string and store it in the secret.
The terraform resource describes the output
key_string - Output only. An encrypted and signed value held by this
key. This field can be accessed only through the GetKeyString method.
I don't know how to call this method in Terraform, to pass the value to a secret version.
This doesn't work.
v1 = { enabled = true, data = resource.google_apikeys_key.maps-api-key.GetKeyString }
Referencing attributes and arguments does not work the way you tried it. You did quote the correct attribute though, but just failed to specify it:
v1 = {
enabled = true,
data = resource.google_apikeys_key.maps-api-key.key_string
}
Make sure to understand how referencing attributes in Terraform works [1].
[1] https://www.terraform.io/language/expressions/references#references-to-resource-attributes

aws secret manager access index

I am trying to retrieve from aws secret manager key value pairs and pass them to my azure SQL Server. Regarding aws secret manager I am using this module.
module "secrets-manager" {
source = "lgallard/secrets-manager/aws"
version = "0.4.1"
secrets = [
{
name = "secretKeyValue"
description = "Secret Key value pair"
secret_key_value = {
username = "username"
password = "password"
}
}
]
}
Then I created a azurerm SQL Server and would like to pass the username and password. What I tried is the following code.
resource "azurerm_sql_server" "sql-server-testing" {
administrator_login = module.secrets-manager.secret_ids[0]
administrator_login_password = module.secrets-manager.secret_ids[0]
location = "westeurope"
name = "sql-name"
resource_group_name = azurerm_resource_group.azure-secrets.name
version = "12.0"
}
I am able to access the secret manager, but it hit only the amazon arn resource and I can't find a way how to pass the secret username and password to my SQL Server.
Thank you very much for any help you can provide
1- Retrieve metadata information about a Secrets Manager secret, via aws secrets manager data resource
data "aws_secretsmanager_secret" "secrets" {
arn = module.secrets-manager.secret_ids[0]
}
data "aws_secretsmanager_secret_version" "current" {
secret_id = data.aws_secretsmanager_secret.secrets.id
}
2- Retrieve a specific value inside that secret (in sql code section)
administrator_login = jsondecode(data.aws_secretsmanager_secret_version.current.secret_string)["username"]
administrator_login_password = jsondecode(data.aws_secretsmanager_secret_version.current.secret_string)["password"]

How to run a Lambda function locally that accesses protected resources

I'm still learning to use AWS Lambda functions. I generated mine using the Amplify framework. The Lambda function I use needs to access an AppSync API. Therefore it has the following middleware:
const tapRoute = f => R.tap(route => route.use(f));
const hydrateClient = tapRoute(async function(req, res, next) {
try {
const url = process.env.API_SAYMAPPSYNCAPI_GRAPHQLAPIENDPOINTOUTPUT;
const region = process.env.REGION;
AWS.config.update({
region,
credentials: new AWS.Credentials(
process.env.AWS_ACCESS_KEY_ID,
process.env.AWS_SECRET_ACCESS_KEY,
process.env.AWS_SESSION_TOKEN
),
});
const credentials = AWS.config.credentials;
const appsyncClient = new AWSAppSyncClient(
{
url,
region,
auth: {
type: 'AWS_IAM',
credentials,
},
disableOffline: true,
},
{
defaultOptions: {
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
},
}
);
const client = await appsyncClient.hydrated();
req.client = client;
next();
} catch (error) {
console.log(error);
next(error);
}
});
As you can see I need to access the environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN. When I run the function in the cloud, it automatically gets the values for these variables. How can I get them locally? Which access key do I need to use and how do I get its secret access key and the session token?
You don't need to explicitly set them if you have configured the ~/.aws/credentials file`.
If you want to configure this file, the easiest way is to simply install the aws-cli and run aws configure. You will be prompted to enter a few values, including AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
If you don't have this file configured, then you can set these values in environment variables yourself.
You can get these values by going to AWS Console -> IAM -> Users -> Select your User -> Security Credentials -> Access Keys. Then you click on "Create Access Key" and either download or write those values down, as AWS_SECRET_ACCESS_KEY is only visible during creation time. AWS_ACCESS_KEY_ID on the other hand is always visible, but it's quite useless if you don't have the secret.
AWS_SESSION_TOKEN is only required if the user in question is using MFA. If not, this value can be ignored.
< MFAOnly >
If you are using MFA though, you will need to use the aws-cli to fetch this value, like so:
aws sts get-session-token --serial-number arn:aws:iam::account-id-number:mfa/your-user --token-code MFAToken
Then, to set the temporary credentials, run aws configure again, replace the values of AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with the new temporary values.
Finally, to set AWS_SESSION_TOKEN, run aws configure set aws_session_token VALUE_RETURNED_FROM_GET_SESSION_TOKEN_COMMAND
< / MFAOnly >
Keep in mind that when running in the Cloud, these credentials are not loaded as you stated. IAM roles are used instead.

aws-sdk-cpp How to decrypt a password encrypted by kms using KMSCLIENT of c++ sdk

im trying to found any example to how decrypt a password encrypted by KMS, for example i have a RDS database password encrypted by KMS, i want to decrypt it in my aws-cpp-lambda function to connect to the database.
i see that for call client Decrypt i need a DecryptRequest;
but i don't know how to initialize it and where set my "encriptedPassword" in the DecryptedRequest to call client.Decrypt()
this is base64
encriptedPassword = "GPK0ujdAAAAZzBlBgkqhkiG"
Aws::SDKOptions options;
InitAPI(options);
{
Aws::Client::ClientConfiguration awsConfig;
awsConfig.region = Aws::Environment::GetEnv("AWS_REGION");
Aws::KMS::KMSClient client(awsConfig);
// Aws::KMS::Model::DecryptRequest decryptRequest;
// client.Decrypt(decryptRequest);
}
// shutdown the aws api
std::cout << "shutdown api" << "\n";
ShutdownAPI(options);
all the credentials are managed and storage by the aws administrator so i don't have access to that configuration, i only have the encrypted db password. when i make the lambda i publish it a git repository after that a jenkins process build and deploy the lambda to aws, jenkins has the credentials etc and i suppose that also is saved in the ec2 or aws config, they only give me a example of how to do that but its in nodejs i need to do a c++ version of that for example this is the nodejs example
use strict'
const AWS = require('aws-sdk');
module.exports.decrypt = (key) => {
return new Promise((resolve, reject) => {
const kms = new AWS.KMS();
console.log('Attempting to decrypt: ' + key);
const params = {CiphertextBlob: new Buffer(key, 'base64')};
console.log(params);
kms.decrypt(params, function (err, data) {
if (err) {
console.log('Error while decrypting key: ' + err);
reject(err)
} else {
console.log('Decrypted key');
resolve(data.Plaintext.toString('ascii'));
}
});
});
what nodejs version do is decrypt the password using sdk kms client after that is passed as simple string to the db connection lib and connect to the database using host, port, db name, etc.
what i need to do is decrypt the password using the KMSCLIENT for c++ like the node version.
anyone cant write a small example please. Thanks to all!!

Configure Postgres application users with Terraform for RDS

Terraform allows you to define Postgres master user and password with the options username and password. But there is no option to set up an application postgres user, how would you do that?
The AWS RDS resource is only used for creating/updating/deleting the RDS resource itself using the AWS APIs.
To create users or databases on the RDS instance itself you'd either want to use another tool (such as psql - the official command line tool or a configuration management tool such as Ansible) or use Terraform's Postgresql provider.
Assuming you've already created your RDS instance you would then connect to the instance as the master user and then create the application user with something like this:
provider "postgresql" {
host = "postgres_server_ip1"
username = "postgres_user"
password = "postgres_password"
}
resource "postgresql_role" "application_role" {
name = "application"
login = true
password = "application-password"
encrypted = true
}
addition to #ydaetskcoR answer, here is the full example for RDS PostgreSQL;
provider "postgresql" {
scheme = "awspostgres"
host = "db.domain.name"
port = "5432"
username = "db_username"
password = "db_password"
superuser = false
}
resource "postgresql_role" "new_db_role" {
name = "new_db_role"
login = true
password = "db_password"
encrypted_password = true
}
resource "postgresql_database" "new_db" {
name = "new_db"
owner = postgresql_role.new_db_role.name
template = "template0"
lc_collate = "C"
connection_limit = -1
allow_connections = true
}
The above two answers requires the host that runs the terraform has direct access to the RDS database, and usually you do not. I propose to code what you need to do in a lambda function (optionally with secrets manager for retrieving the master password):
resource "aws_lambda_function" "terraform_lambda_func" {
filename = "${path.module}/lambda_function/lambda_function.zip"
...
}
and then use the following data source (example) to call the lambda function.
data "aws_lambda_invocation" "create_app_user" {
function_name = aws_lambda_function.terraform_lambda_func.function_name
input = <<-JSON
{
"step": "create_app_user"
}
JSON
depends_on = [aws_lambda_function.terraform_lambda_func]
provider = aws.primary
}
This solution id generic. It can do what a lambda function can do with AWS API can do, which is basically limitless.