Eray
Eray

Reputation: 7128

Setting CodeDeploy deployment environment variables

I have a CD pipeline for my NodeJS app and the pipeline contains these steps:

1) Travis CI uploads the master branch to S3 as a zip file

2) Travis CI triggers AWS CodeDeploy deployment

3) CodeDeploy grabs the .zip file, extracts it to my AWS EC2 and runs the app

But my NodeJS app needs some environment variables to run. Since values of these variables are sensitive, I'm storing these vars in TravisCI's Repository Settings and don't have a clue how to pass my environment variables from Travis to EC2.

I can use env attribute of the appspec.yml (for CodeDeploy) but my env. vars containing sensitive info which shouldn't be in the code repository.

Is there any best practice to pass my env. vars. from Travis to EC2 instance through CodeDeploy?

For now what I am doing is, generating a .env file during the Travis build and adding it to .zip file, so when the app is deployed to EC2, I can reach them by using dotenv package of NodeJS. But I don't think this is the best approach.

Upvotes: 6

Views: 3912

Answers (6)

Matthew Allen
Matthew Allen

Reputation: 589

Hate the fact all these work-arounds are necessary. If appspec lets you call a script, you should be able to pass in parameters. It's silly there isn't even a built in variable with the artifact's name.

I've started generating simple ephemeral "caller scripts" in my CodeBuild (or whatever generates the artifact that CodeDeploy uses). So for example, if I want to run a script named NotifyTeams.ps1 in my CodeDeploy, and it requires a parameter named Message, then in the CodeBuild buildspec.yml I have this:

post_build: 
    commands:
      - Set-Content -Path ".\Scripts\PowerShell\CallNotifyTeams.ps1" -Value "& .\NotifyTeams.ps1 '$AppName $AppVersion was deployed';"

Then in the CodeDeploy appspec.ml that deploys the artifact generated by this CodeBuild job, I run the CallNotifyTeams.ps1 script.

hooks:
  AfterInstall:
    - location: \Scripts\Powershell\CallNotifyTeams.ps1

In my example I set the $AppName and $AppVersion in the buildspec.yml. And bash is prob easier, but I'm stuck with some legacy Windows apps in this example.

Upvotes: 0

saj
saj

Reputation: 21

A developer friendly option is to use AWS AppConfig to host configuration files. A developer can easily log into AWS and copy the .env file as an AppConfig hosted configuration. When the code deploys, your deploy script can pull these files from AWS Config.

This this more developer friendly as the they can edit the .env file directly in AppConfig Configuration via browser. AppConfig encrypts the data also keeps track of versioning and environments.

Reading Materials:

What is AWS AppConfig? Hosted Configurations

Upvotes: 2

Prashanna
Prashanna

Reputation: 1001

You can set the environment variables under the hooks section of code deploy by writing a shell script in after install stage of code deploy after the zip is deployed the after install script will where you can set the env variables of node js and start your pm2 server

Upvotes: 0

Vaibs
Vaibs

Reputation: 1606

You can use the aws parameter store service. By using that service you can store your environment variable also you can apply encryption on the variable.

Please check below link::

https://aws.amazon.com/blogs/mt/the-right-way-to-store-secrets-using-parameter-store/

https://aws.amazon.com/systems-manager/features/

https://www.npmjs.com/package/aws-param-store

Upvotes: 0

raevilman
raevilman

Reputation: 3249

You can use AWS System Manager's Parameter store at below link for this https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html

Quick info:

AWS Systems Manager provides a centralized store to manage your configuration data, whether plain-text data such as database strings or secrets such as passwords. This allows you to separate your secrets and configuration data from your code. Parameters can be tagged and organized into hierarchies, helping you manage parameters more easily. For example, you can use the same parameter name, "db-string", with a different hierarchical path, "dev/db-string” or “prod/db-string", to store different values. Systems Manager is integrated with AWS Key Management Service (KMS), allowing you to automatically encrypt the data you store. You can also control user and resource access to parameters using AWS Identity and Access Management (IAM). Parameters can be referenced through other AWS services, such as Amazon Elastic Container Service, AWS Lambda, and AWS CloudFormation. (source: https://aws.amazon.com/systems-manager/features/#Parameter_Store)

Upvotes: 0

deosha
deosha

Reputation: 992

You can have them in encrypted format in S3(not as part of code of course) and fetch them before deployment and remove after deployment. You can also use https://www.vaultproject.io/ .

Upvotes: 1

Related Questions