{"id":412,"date":"2023-01-05T14:46:08","date_gmt":"2023-01-05T14:46:08","guid":{"rendered":"https:\/\/computeoncloud.eu\/?p=412"},"modified":"2023-01-05T14:46:08","modified_gmt":"2023-01-05T14:46:08","slug":"loading-configurations-based-on-environment-in-aws-codedeploy","status":"publish","type":"post","link":"https:\/\/computeoncloud.eu\/index.php\/2023\/01\/05\/loading-configurations-based-on-environment-in-aws-codedeploy\/","title":{"rendered":"Loading Configurations Based on Environment in AWS CodeDeploy"},"content":{"rendered":"\n<p id=\"f1ca\">The project I\u2019ve been working on for some time has multiple environments for multiple clients and each environment has its environment configurations. Therefore, I needed a secure way to store the environment configurations and to fetch them in real-time while the application was being deployed.<\/p>\n\n\n\n<p id=\"2f1c\">After doing some research, I found that AWS provides&nbsp;<a href=\"https:\/\/aws.amazon.com\/blogs\/devops\/using-codedeploy-environment-variables\/\" rel=\"noreferrer noopener\" target=\"_blank\">Environment Variables<\/a>&nbsp;for AWS CodeDeploy during deployment that we can use with lifecycle event hooks.<\/p>\n\n\n\n<p id=\"d7f3\">I came across the idea to store environment<strong>&nbsp;<\/strong>configurations as a secret in&nbsp;<strong>AWS Secrets Manager<\/strong>&nbsp;with name same as CodeDeploy deployment<strong>&nbsp;<\/strong>group<strong>&nbsp;<\/strong>name; and fetch the configurations using&nbsp;<strong>DEPLOYMENT_GROUP_NAME<\/strong>&nbsp;environment variable amidst the deployment.<\/p>\n\n\n\n<p id=\"c7c3\">e.g. If we have a deployment group with name&nbsp;<strong>Client-Dashboard-DG,<\/strong>&nbsp;we\u2019ll also store the secret in secret manager with the same name<strong>.<\/strong><\/p>\n\n\n\n<p id=\"2c38\">Next, in the appspec.yml file, we will execute a bash script to get the secrets from the AWS Secret Manager. This is how our `appspec.yml` file would look like<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">hooks:<br>  BeforeInstall:<br>    - location: scripts\/getconfig.sh<br>      timeout: 600<br>      runas: root<\/pre>\n\n\n\n<p id=\"318c\">And `getconfig.sh` file would look like this<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n\ncd \/opt\/codedeploy-agent\/deployment-root\/${DEPLOYMENT_GROUP_ID}\/${DEPLOYMENT_ID}\/deployment-archive\/export \n\nNODE_PATH=\/usr\/lib\/node_modules\/\n\nnode scripts\/secret-manager-to-env.js<\/pre>\n\n\n\n<p id=\"5777\">Our JS file to get the secrets would look like<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Use this code snippet in your app.\n\/\/ If you need more information about configurations or implementing the sample code, visit the AWS docs:\n\/\/ https:\/\/aws.amazon.com\/developers\/getting-started\/nodejs\/\n\n\/\/ Load the AWS SDK\nDEPLOYMENT_GROUP_NAME = process.env.DEPLOYMENT_GROUP_NAME\n\nvar AWS = require('aws-sdk'),\n    region = \"us-west-2\",\n    secretName = `${DEPLOYMENT_GROUP_NAME}`,\n    secret,\n    decodedBinarySecret;\nvar fs = require('fs');\n\n\/\/ Create a Secrets Manager client\nvar client = new AWS.SecretsManager({\n    region: region\n});\n\n\/\/ In this sample we only handle the specific exceptions for the 'GetSecretValue' API.\n\/\/ See https:\/\/docs.aws.amazon.com\/secretsmanager\/latest\/apireference\/API_GetSecretValue.html\n\/\/ We rethrow the exception by default.\n\nclient.getSecretValue({SecretId: secretName}, function(err, data) {\n    if (err) {\n        console.log(\"*******************************\")\n        console.log(\"Error fetching secrets\")\n        console.log(\"*******************************\")\n        process.exit(1);\n\tif (err.code === 'DecryptionFailureException')\n            \/\/ Secrets Manager can't decrypt the protected secret text using the provided KMS key.\n            \/\/ Deal with the exception here, and\/or rethrow at your discretion.\n            throw err;\n        else if (err.code === 'InternalServiceErrorException')\n            \/\/ An error occurred on the server side.\n            \/\/ Deal with the exception here, and\/or rethrow at your discretion.\n            throw err;\n        else if (err.code === 'InvalidParameterException')\n            \/\/ You provided an invalid value for a parameter.\n            \/\/ Deal with the exception here, and\/or rethrow at your discretion.\n            throw err;\n        else if (err.code === 'InvalidRequestException')\n            \/\/ You provided a parameter value that is not valid for the current state of the resource.\n            \/\/ Deal with the exception here, and\/or rethrow at your discretion.\n            throw err;\n        else if (err.code === 'ResourceNotFoundException')\n            \/\/ We can't find the resource that you asked for.\n            \/\/ Deal with the exception here, and\/or rethrow at your discretion.\n            throw err;\n    }\n    else {\n        \/\/ Decrypts secret using the associated KMS CMK.\n        \/\/ Depending on whether the secret is a string or binary, one of these fields will be populated.\n        if ('SecretString' in data) {\n            secret = JSON.parse(data.SecretString);\n            for (let key in secret) {\n                if(secret.hasOwnProperty(key))\n                fs.appendFile('.env', `${key}='${secret&#91;key]}'` + '\\r\\n', function (err) {\n                        if (err) throw err;\n                        console.log(`${key}='${secret&#91;key]}' Saved!`);\n                });\n            }\n\n        } else {\n            let buff = new Buffer(data.SecretBinary, 'base64');\n            decodedBinarySecret = buff.toString('ascii');\n        }\n    }\n    \n    \/\/ Your code goes here. \n});<\/code><\/pre>\n\n\n\n<p id=\"e48d\">And, you may find\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/MrHassanMurtaza\/parse-env-to-secretmanager\" target=\"_blank\">this script<\/a>\u00a0helpful and clap if it does <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The project I\u2019ve been working on for some time has multiple environments for multiple clients and each environment has its environment configurations. Therefore, I needed a secure way to store the environment configurations and to fetch them in real-time while the application was being deployed. After doing some research, I found that AWS provides&nbsp;Environment Variables&nbsp;for &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"\" href=\"https:\/\/computeoncloud.eu\/index.php\/2023\/01\/05\/loading-configurations-based-on-environment-in-aws-codedeploy\/\"> <span class=\"screen-reader-text\">Loading Configurations Based on Environment in AWS CodeDeploy<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,16,15],"tags":[],"class_list":["post-412","post","type-post","status-publish","format-standard","hentry","category-aws","category-codedeploy","category-codepipeline"],"_links":{"self":[{"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/posts\/412","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/comments?post=412"}],"version-history":[{"count":1,"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/posts\/412\/revisions"}],"predecessor-version":[{"id":413,"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/posts\/412\/revisions\/413"}],"wp:attachment":[{"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/media?parent=412"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/categories?post=412"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computeoncloud.eu\/index.php\/wp-json\/wp\/v2\/tags?post=412"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}