I am trying to write a script for testing my API which is deployed in AWS EKS in Cloudwatch synthetics (Canary). But I don't see the provision to add my certificate and key along with my API request.
How can I insert certificate along with the request header of the API? In my local I am appending the certificates using fs and append it to the axios headers. If the certificate needs to be append in puppeteer script, how can I achieve it?
ERROR: Request failed. Request: https://myapirequestdns.com/api/v1.0/testroute/testdomain ERROR: Failure reason: Error: read ECONNRESET Stack: Error: read ECONNRESET at TLSWrap.onStreamRead (internal/stream_base_commons.js:209:20) at TLSWrap.callbackTrampoline (internal/async_hooks.js:130:17)
This is the code we use at the top of our canary function running syn-nodejs-puppeteer-3.5 to retrieve and use a certificate, private key, and CA from AWS secrets manager:
const synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const syntheticsConfiguration = synthetics.getConfiguration();
const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
const secretsManager = new AWS.SecretsManager();
// We need to load a client certificate to authenticate to endpoints that require mTLS, specified in these env variables
const secretName = process.env.SECRET_NAME
const keyItemName = process.env.KEY_ITEM_NAME
const certItemName = process.env.CERT_ITEM_NAME
const caItemName = process.env.CA_ITEM_NAME
// Function to retrieve specified key/cert from specified secret and return them as plain strings
const getKeyAndCertAndCA = async function () {
// Retrieve secret
const data = await secretsManager.getSecretValue({SecretId: process.env.SECRET_NAME}).promise();
// Turn secret string into object
const secret = JSON.parse(data.SecretString);
// Base64 decode the cert and key and return them
const key = Buffer.from(secret[keyItemName], 'base64').toString('ascii');
const cert = Buffer.from(secret[certItemName], 'base64').toString('ascii');
const ca = Buffer.from(secret[caItemName], 'base64').toString('ascii');
return [ key, cert, ca ];
}
Then, just inside the apiCanaryBlueprint function, load the key/cert/CA
const apiCanaryBlueprint = async function () {
// Load TLS client cert and key for calls requiring TLS
const [ key, cert, ca ] = await getKeyAndCertAndCA();
and then later, when setting requestOptions, specify the key, cert, and ca parameters:
let requestOptions = {
hostname: url.host,
method: 'GET',
path: url.path,
port: '443',
protocol: 'https:',
body: "",
headers: {},
key: key,
cert: cert,
ca: ca
};