<p>There are, as always, a few ways to solve this.</p>

<p>You can use a central source to keep secrets that each server reads from ala <a href="https://www.vaultproject.io/" rel="noreferrer">Hashicorp Vault</a>. While popular this is not my preferred approach as its rather complex. There are quite a few key value stores that can provide similar functionality such as <a href="https://aws.amazon.com/ec2/systems-manager/parameter-store/" rel="noreferrer">AWS Parameter Store</a>.</p>

<p>You can manually put data in these stores and/or store it encrypted in git. Using tools such as <a href="https://github.com/kubernetes/kops/blob/master/README.md" rel="noreferrer">kops</a> (AWS only) or <a href="https://github.com/Shopify/ejson/blob/master/README.md" rel="noreferrer">ejson</a> (provider agnostic) you can have the secrets in the same repo as the app. Then have the app either fetch all the secrets at deploy time or just the decryption key so it can load the encrypted file.</p>

CC BY-SA 3.0
2017-09-02T02:38:19.993Z
Side note - kops is no longer AWS-only, from its link: `with GCE and VMware vSphere in alpha and other platforms planned`
Dan Cornilescu
CC BY-SA 3.0
2017-09-16T12:26:16.497Z
OK, so would it be possible to create an Azure key vault in my terraform config, and then configure my app service to be approved for access to the sql credentials? (I currently create the sql server, DBs and app service all in a resource group in my terraform config). That way I can safely just call to the key vault in my code, but it will only work in the production environment?
George Edwards
CC BY-SA 3.0
2017-09-16T13:20:14.687Z
To put it another way, if I have a [SQL Server](https://www.terraform.io/docs/providers/azurerm/r/sql_server.html) specified in terraform, I have to write in its username and password, to create a [key vault secret](https://www.terraform.io/docs/providers/azurerm/r/key_vault_secret.html), I also have to specify the secret (SQL password). How do I get around this
George Edwards
CC BY-SA 3.0
2017-09-16T22:23:38.297Z
Don't manage it with Terraform. Managing secrets requires a tool that's dedicated to the task usually, Terraform isn't. I dont have any suggestions what to use since I've not used Azure
Robo
CC BY-SA 3.0
2017-09-01T22:49:13.700Z
2017-09-02T02:35:51.113Z
2017-09-02T02:35:51.113Z
Robo
<p>This is a common problem in configuration management, and while I can't speak for Chef as I haven't worked with it, I can tell you how this is solved by both Puppet and SaltStack.</p>

<p>Firstly, this distinction becomes a little less important with interpreted languages since there isn't much difference between including this sensitive data in a configuration file and including it in a text file that is interpreted (and I'm not aware of any compiled configuration management systems)</p>

<p>But secondly, both <a href="https://docs.puppet.com/puppet/3/lang_import.html" rel="nofollow noreferrer">Puppet</a> and <a href="https://docs.saltstack.com/en/getstarted/config/include.html" rel="nofollow noreferrer">SaltStack</a>, so you can simply make the equivalent of a .env file and include it just as you do with your applications.</p>

<p>Typically this is not the recommended approach however. Instead, SaltStack recommends you use <a href="https://docs.saltstack.com/en/latest/topics/pillar/" rel="nofollow noreferrer">Pillars</a> for managing this data, which are stored separately from the code (called "States"). This pillar data is uniquely calculated for each minion and sent directly from the server only to the minion only using standard SSL encryption - so one minion cannot see another's pillar data. In fact, minions can't edit pillar data and they <em>definitely</em> can't rewrite pillar data <em>on the server</em> - this data is unicast only.</p>

<p>Similarly, <a href="https://docs.puppet.com/puppet/4.10/hiera_intro.html" rel="nofollow noreferrer">Puppet utilizes Heira</a> for achieving something very similar. This allows you to store your code and metadata separately. You will then reference the pillar in your salt state or heira value in your manifest using a variable/function call thereby allowing your code to populate these values at runtime. </p>

CC BY-SA 3.0
2017-09-02T02:41:15.033Z
The question is about a webapp and makes no mention of Config Management tools. While you could use config management you havent mentioned the encryption implementations at all such as hiera-gpg
Robo
CC BY-SA 3.0
2017-09-02T02:58:38.160Z
@Robo - Even infrastructure must be configured - and it can be configured with a configuration management tool. For example, [Puppet](https://forge.puppet.com/puppetlabs/f5) and [Salt](https://docs.saltstack.com/en/latest/ref/states/all/salt.states.bigip.html) have plugins for managing your load balancer. [Cisco's ACI fabric has a puppet agent](https://puppet.com/blog/cisco-aci-infrastructure-exists-for-applications) and there is a [puppet module for VMWare NSX](https://github.com/vmware/vmware-nsx) or you can use [Cisco NSO to manage a range of devices](https://goo.gl/6vND1b).
James Shewey
CC BY-SA 3.0
2017-09-02T03:02:56.107Z
You can manage Open Stack with these, AWS and more. And anything that has an API can be configured even if there isn't already a module for it by punting and creating a module using ruby or python (respectively). Configuration management tools are built to configure infrastructure, not merely servers. And yes, I did not mention hiera gpg, since the OP asked about separating the data, not encrypting it. But this is nonetheless a great point worth noting. You can also *encrypt* your metadata, not just store it separately.
James Shewey
CC BY-SA 3.0
2017-09-01T18:30:10.823Z
2017-09-01T18:30:10.823Z
James Shewey
<p>When developing a Web App, and trying to adhere to what is generally considered best practice, e.g. <a href="https://12factor.net/" rel="noreferrer">The 12 factor app</a> methodology etc. One key concept is to keep configuration and sensitive data out of your source code - access keys, connection strings etc. Using something like <code>.env</code> files to set different connection strings for a dev, test and production environment.</p>

<p>However, another key point (not sure is is mentioned in the 12 factor app), seems to be Infrastructure as Code. I completely see the benefit of this, however, I don't see how it can be reconciled with not storing/hard coding sensative data. Surely to entirely automate the provisioning of a new environment, a series of env variables has to be specified - in code...</p>

<p>How can these two seemingly contradictory pieces of standard practices be reconciled? </p>

<p>My current approach is something like this:</p>

<ol>
<li><p>Hosted Git Repo with however many dev branches and a master branch</p></li>
<li><p>When dev branches are merged with master branch, the CI build is triggered, this builds the project and runs unit and integration tests. </p></li>
<li><p>The git repo also has a production branch, when master is merged into production, the same build runs, but if it is successful, a CD release is created. (In my case this is a deployment to an Azure App Service)</p></li>
</ol>

<p>So my three environments are the local dev machines (before a PR into the master branch in the hosted repo), the CI build server and the production app service. At the moment, locally we have a <code>.env</code> file which isn't checked into the git repo. On the CI server, the <code>NODE_ENV</code> value is set to test, so the code uses hard-coded unit test values (nothing sensitive). Then in production we manually set the connection strings etc. in the app service settings. This, I feel, is potentially an issue. </p>

<p>So possibly I could add an infrastructure folder to the repo, with Terraform code in it, then as part of the release process, terraform plan could see if there is anything that needs changing between the code's infrastrucutre and the real world infrastructure (and if so, execute it). But where do I store the production env variables?</p>

CC BY-SA 3.0
2017-09-01T14:13:07.440Z
Usual answer to this is use a king of secret storage, etc, consul, vault. this way your secrets are not stored with the code and are handled on a separate system (which need backups of course)
Tensibai
<continuous-integration><continuous-delivery><terraform><environments><infrastructure-as-code>
How to reconcile Infrastructure as Code and not storing env config in code?
George Edwards
# How to reconcile Infrastructure as Code and not storing env config in code?

(Asked by: username_0 on 2017-09-01)

When developing a Web App, and trying to adhere to what is generally considered best practice, e.g. [The 12 factor app](https://12factor.net/) methodology etc. One key concept is to keep configuration and sensitive data out of your source code - access keys, connection strings etc. Using something like `.env` files to set different connection strings for a dev, test and production environment.

However, another key point (not sure is is mentioned in the 12 factor app), seems to be Infrastructure as Code. I completely see the benefit of this, however, I don't see how it can be reconciled with not storing/hard coding sensative data. Surely to entirely automate the provisioning of a new environment, a series of env variables has to be specified - in code...

How can these two seemingly contradictory pieces of standard practices be reconciled?

My current approach is something like this:

1. Hosted Git Repo with however many dev branches and a master branch
2. When dev branches are merged with master branch, the CI build is triggered, this builds the project and runs unit and integration tests.
3. The git repo also has a production branch, when master is merged into production, the same build runs, but if it is successful, a CD release is created. (In my case this is a deployment to an Azure App Service)

So my three environments are the local dev machines (before a PR into the master branch in the hosted repo), the CI build server and the production app service. At the moment, locally we have a `.env` file which isn't checked into the git repo. On the CI server, the `NODE_ENV` value is set to test, so the code uses hard-coded unit test values (nothing sensitive). Then in production we manually set the connection strings etc. in the app service settings. This, I feel, is potentially an issue.

So possibly I could add an infrastructure folder to the repo, with Terraform code in it, then as part of the release process, terraform plan could see if there is anything that needs changing between the code's infrastrucutre and the real world infrastructure (and if so, execute it). But where do I store the production env variables?

**Tags:** continuous-integration, continuous-delivery, terraform, environments, infrastructure-as-code

> **Comments:**
> **username_1**: Usual answer to this is use a king of secret storage, etc, consul, vault. this way your secrets are not stored with the code and are handled on a separate system (which need backups of course)  

---

## 2 answers

### Answer by username_2 on 2017-09-01. Score: 5

There are, as always, a few ways to solve this.

You can use a central source to keep secrets that each server reads from ala [Hashicorp Vault](https://www.vaultproject.io/). While popular this is not my preferred approach as its rather complex. There are quite a few key value stores that can provide similar functionality such as [AWS Parameter Store](https://aws.amazon.com/ec2/systems-manager/parameter-store/).

You can manually put data in these stores and/or store it encrypted in git. Using tools such as [kops](https://github.com/kubernetes/kops/blob/master/README.md) (AWS only) or [ejson](https://github.com/Shopify/ejson/blob/master/README.md) (provider agnostic) you can have the secrets in the same repo as the app. Then have the app either fetch all the secrets at deploy time or just the decryption key so it can load the encrypted file.

> **Comments:**
> **username_3**: Side note - kops is no longer AWS-only, from its link: `with GCE and VMware vSphere in alpha and other platforms planned`  
> **username_0**: OK, so would it be possible to create an Azure key vault in my terraform config, and then configure my app service to be approved for access to the sql credentials? (I currently create the sql server, DBs and app service all in a resource group in my terraform config). That way I can safely just call to the key vault in my code, but it will only work in the production environment?  
> **username_0**: To put it another way, if I have a [SQL Server](https://www.terraform.io/docs/providers/azurerm/r/sql_server.html) specified in terraform, I have to write in its username and password, to create a [key vault secret](https://www.terraform.io/docs/providers/azurerm/r/key_vault_secret.html), I also have to specify the secret (SQL password). How do I get around this  
> **username_2**: Don't manage it with Terraform. Managing secrets requires a tool that's dedicated to the task usually, Terraform isn't. I dont have any suggestions what to use since I've not used Azure  

---

### Answer by username_4 on 2017-09-01. Score: 2

This is a common problem in configuration management, and while I can't speak for Chef as I haven't worked with it, I can tell you how this is solved by both Puppet and SaltStack.

Firstly, this distinction becomes a little less important with interpreted languages since there isn't much difference between including this sensitive data in a configuration file and including it in a text file that is interpreted (and I'm not aware of any compiled configuration management systems)

But secondly, both [Puppet](https://docs.puppet.com/puppet/3/lang_import.html) and [SaltStack](https://docs.saltstack.com/en/getstarted/config/include.html), so you can simply make the equivalent of a .env file and include it just as you do with your applications.

Typically this is not the recommended approach however. Instead, SaltStack recommends you use [Pillars](https://docs.saltstack.com/en/latest/topics/pillar/) for managing this data, which are stored separately from the code (called "States"). This pillar data is uniquely calculated for each minion and sent directly from the server only to the minion only using standard SSL encryption - so one minion cannot see another's pillar data. In fact, minions can't edit pillar data and they *definitely* can't rewrite pillar data *on the server* - this data is unicast only.

Similarly, [Puppet utilizes Heira](https://docs.puppet.com/puppet/4.10/hiera_intro.html) for achieving something very similar. This allows you to store your code and metadata separately. You will then reference the pillar in your salt state or heira value in your manifest using a variable/function call thereby allowing your code to populate these values at runtime.

> **Comments:**
> **username_2**: The question is about a webapp and makes no mention of Config Management tools. While you could use config management you havent mentioned the encryption implementations at all such as hiera-gpg  
> **username_4**: @username_2 - Even infrastructure must be configured - and it can be configured with a configuration management tool. For example, [Puppet](https://forge.puppet.com/puppetlabs/f5) and [Salt](https://docs.saltstack.com/en/latest/ref/states/all/salt.states.bigip.html) have plugins for managing your load balancer. [Cisco's ACI fabric has a puppet agent](https://puppet.com/blog/cisco-aci-infrastructure-exists-for-applications) and there is a [puppet module for VMWare NSX](https://github.com/vmware/vmware-nsx) or you can use [Cisco NSO to manage a range of devices](https://goo.gl/6vND1b).  
> **username_4**: You can manage Open Stack with these, AWS and more. And anything that has an API can be configured even if there isn't already a module for it by punting and creating a module using ruby or python (respectively). Configuration management tools are built to configure infrastructure, not merely servers. And yes, I did not mention hiera gpg, since the OP asked about separating the data, not encrypting it. But this is nonetheless a great point worth noting. You can also *encrypt* your metadata, not just store it separately.  

---

