<p>Ok so I understand that you are in AWS and Docker already and Terraform is something you want to bring into picture for IaaC. and Yes, docker for production. Now, let's start with environment:
Assume you have three environments, Dev, Test and Prod. So you create three folders, Dev, Test and Prod which contain infra code for three environments. Now, I don't understand what you mean by infrastructure provided by docker but docker will contain your web servers and web application. Number of containers will depend on how large or small your application is and are you in micro services architecture. So what Terraform does for you is creating almost everything: Right from network structure(VPC, subnets, NACLs, gateways etc), autoscaling groups(I prefer this as you may want to use docker orchestration), security groups, IAM roles, policies to RDS and ECS etc.</p>

<p>So you can tag them in your code as per their environment and you create each of these components using Terraform modules. </p>

<p>So now you have Terraform code which creates infrastructure for you. Store your state file in S3 because you want consistency in your infrastructure state. Keep your database state file separate from other state files. You may want to have separate state files for your network, security groups, RDS, IAM, Cloudwatch etc. </p>

<p>Now comes the deployment part: Since you are in Docker, why don't you use AWS ECS? It will be easy deployment (Almost zero downtime) and orchestration will be managed by ECS itself. So now even deployment you can do using Terraform. Maintain a separate state file for this too. </p>

<p>You can create separate docker images for dev, test and production during your CI. If you do not have any docker tagging strategy, you may use $BUILD_NUMBER:$ENV for now. One of the purpose of using docker is that you don't need to care about where you want to run the container so identical docker images for Dev, Test and Production is almost always ok with some configuration changes. </p>

<p>You do not create anything locally. Use CI/CD tools such as combo of Jenkins and Git which triggers everything. </p>

CC BY-SA 4.0
2019-02-06T17:33:44.463Z
"provided by docker" I mean using terraform docker provider. Dockerfiles has all the scripts needed to setup an environment. But I don't want use Docker in production, as we have EC2. Furthermore, we are poor, I cannot afford AWS for dev, testing and prod, so we need something locally
Glasnhost
CC BY-SA 4.0
2019-02-07T03:55:54.607Z
But why don't you run docker on EC2? Why do you want overhead of more defects when app actually runs on AWS? Docker still needs a machine to run on: the host machine. So suppose you have one t2.medium ec2 instance. You can have 2 t2.small in lieu of that and use docker orchestration and cost will be same with better reliability and availability. @Glasnhost
deosha
CC BY-SA 4.0
2019-02-07T16:41:20.573Z
let's say we have few human resources and I don't "trust" docker for production straight away. We have EC2 machines that are currently fine. I'm being very conservative here, but not having much devops skills nor docker knowledge I'd rather go on like this and switch gradually. Docker is however very handy for testing new configurations locally
Glasnhost
CC BY-SA 4.0
2019-02-08T02:36:02.747Z
Even then, I would recommend using CI rather that creating docker containers locally. So you can setup a CI Jenkins machine and team can push code to say Git and CI automation can do that(You can use multibranch pipeline). You are good with deployment with Ansible. However, the EC2 machines for production, network, load balancers etc you should create using Terraform. And yes, you can use Ansible provider of Terraform for deployment. If you use docker provider to create containers, it's ok.
deosha
CC BY-SA 4.0
2019-02-11T22:08:28.997Z
@deoash but where do your team develop? How do I setup an uniform environment for everybody and where do I test configurations changes, machine upgrades etc? Our web app doesn't have any "build" process (php) We rather need to test integration. Ins't Docker for that?
Glasnhost
CC BY-SA 4.0
2019-02-12T02:52:04.563Z
It's quite difficult to do the development inside docker. Generally teams develop in their local machines, push to git, CI process ensures that everything is fine and CI takes place on uniform system. Docker is certainly not for development from scratch but for packaging the already developed code
deosha
CC BY-SA 4.0
2019-02-13T21:20:32.100Z
why so? I find quite easy to setup with docker different environments  whit different os, stacks and versions to test performance, upgrades etc. Why do you see Docker "certainly NOT" for development? I can also give a docker file or an image to a new developer and setup everything immediately.
Glasnhost
CC BY-SA 4.0
2019-02-06T05:45:02.280Z
2019-02-06T05:45:02.280Z
deosha
<p>Here two parts: use IaC tools like Terraform to create environments and use Docker to deploy applications. </p>

<p>1) You can use Terraform with workspaces to make production and development. Maybe use Packer to prepare AMI images to reduce time for building.</p>

<p>2) Decide what CI/CD pipeline you will use to deploy apps. And first of all here you should know what orchestration tool you will use for Docker containers - compose, swarm, nomad, kubernetes.</p>

CC BY-SA 4.0
2019-03-23T06:36:39.393Z
2019-03-23T06:36:39.393Z
Vasiliy  Shakhunov
<p>If I understand your need:</p>

<ul>
<li>Need Infrastructure as Code.</li>
<li>Configuration management.</li>
</ul>

<p>Terraform is a great tool for creating your infrastructure. It has API support for AWS, GCP and almost all the cloud providers. Now that your infrastructure is ready, you need to configure the same using tools like (CHEF, Ansible or Puppet). I have personally bootstrapped the nodes created by Terraform to CHEF and have run cookbooks.</p>

CC BY-SA 4.0
2019-02-11T22:10:52.637Z
Ok I understand that I provide the infrastructure with terraform and "provide"  the machines with something like Ansible. But I'm think already about using Docker for local development, to test machine upgrades and environments. So I guess I must repeat the Dockerfile instructions almost the same for Ansible when I deploy?
Glasnhost
CC BY-SA 4.0
2019-02-12T08:12:51.520Z
What about trying with Vagrant? Docker files is also an option, but how do we network between the container , Docker-compose?
Sunil
CC BY-SA 4.0
2019-02-08T10:38:57.797Z
2019-03-23T06:09:38.693Z
2019-03-23T06:09:38.693Z
Sunil
<p>We have a typical multi layered web application:  a balancer, 2 web server 2 db server.</p>

<p>I feel we strongly need to start using a kind of Infrastructure As Code in order to replicate easily environments, testing infrastructure updates, control production servers.</p>

<p>I've never done that and I'm struggling to understand the workflow.
I'm thinking something like this:</p>

<ul>
<li><p>create locally my machines with docker and Dockerfiles.</p></li>
<li><p>use terraform to setup locally the infrastructure provided by docker (or docker-compose?).</p></li>
<li><p>reuse in some way the Dockerfiles to provide the production or staging machine (we don't use Docker in production, but rather AWS with EC2/AMI and RDS).</p></li>
<li><p>use ansible to deploy the application.</p></li>
</ul>

<p>I'm not sure this is the way. Or maybe it's too complex</p>

<docker><terraform><infrastructure-as-code>
How to structure a IaC for production, and development?
Glasnhost
# How to structure a IaC for production, and development?

(Asked by: username_0 on 2019-02-04)

We have a typical multi layered web application: a balancer, 2 web server 2 db server.

I feel we strongly need to start using a kind of Infrastructure As Code in order to replicate easily environments, testing infrastructure updates, control production servers.

I've never done that and I'm struggling to understand the workflow.
I'm thinking something like this:

* create locally my machines with docker and Dockerfiles.
* use terraform to setup locally the infrastructure provided by docker (or docker-compose?).
* reuse in some way the Dockerfiles to provide the production or staging machine (we don't use Docker in production, but rather AWS with EC2/AMI and RDS).
* use ansible to deploy the application.

I'm not sure this is the way. Or maybe it's too complex

**Tags:** docker, terraform, infrastructure-as-code


---

## 3 answers

### Answer by username_1 on 2019-02-06. Score: 1 | Accepted answer

Ok so I understand that you are in AWS and Docker already and Terraform is something you want to bring into picture for IaaC. and Yes, docker for production. Now, let's start with environment:
Assume you have three environments, Dev, Test and Prod. So you create three folders, Dev, Test and Prod which contain infra code for three environments. Now, I don't understand what you mean by infrastructure provided by docker but docker will contain your web servers and web application. Number of containers will depend on how large or small your application is and are you in micro services architecture. So what Terraform does for you is creating almost everything: Right from network structure(VPC, subnets, NACLs, gateways etc), autoscaling groups(I prefer this as you may want to use docker orchestration), security groups, IAM roles, policies to RDS and ECS etc.

So you can tag them in your code as per their environment and you create each of these components using Terraform modules.

So now you have Terraform code which creates infrastructure for you. Store your state file in S3 because you want consistency in your infrastructure state. Keep your database state file separate from other state files. You may want to have separate state files for your network, security groups, RDS, IAM, Cloudwatch etc.

Now comes the deployment part: Since you are in Docker, why don't you use AWS ECS? It will be easy deployment (Almost zero downtime) and orchestration will be managed by ECS itself. So now even deployment you can do using Terraform. Maintain a separate state file for this too.

You can create separate docker images for dev, test and production during your CI. If you do not have any docker tagging strategy, you may use $BUILD\_NUMBER:$ENV for now. One of the purpose of using docker is that you don't need to care about where you want to run the container so identical docker images for Dev, Test and Production is almost always ok with some configuration changes.

You do not create anything locally. Use CI/CD tools such as combo of Jenkins and Git which triggers everything.

> **Comments:**
> **username_0**: "provided by docker" I mean using terraform docker provider. Dockerfiles has all the scripts needed to setup an environment. But I don't want use Docker in production, as we have EC2. Furthermore, we are poor, I cannot afford AWS for dev, testing and prod, so we need something locally  
> **username_1**: But why don't you run docker on EC2? Why do you want overhead of more defects when app actually runs on AWS? Docker still needs a machine to run on: the host machine. So suppose you have one t2.medium ec2 instance. You can have 2 t2.small in lieu of that and use docker orchestration and cost will be same with better reliability and availability. @username_0  
> **username_0**: let's say we have few human resources and I don't "trust" docker for production straight away. We have EC2 machines that are currently fine. I'm being very conservative here, but not having much devops skills nor docker knowledge I'd rather go on like this and switch gradually. Docker is however very handy for testing new configurations locally  
> **username_1**: Even then, I would recommend using CI rather that creating docker containers locally. So you can setup a CI Jenkins machine and team can push code to say Git and CI automation can do that(You can use multibranch pipeline). You are good with deployment with Ansible. However, the EC2 machines for production, network, load balancers etc you should create using Terraform. And yes, you can use Ansible provider of Terraform for deployment. If you use docker provider to create containers, it's ok.  
> **username_0**: @deoash but where do your team develop? How do I setup an uniform environment for everybody and where do I test configurations changes, machine upgrades etc? Our web app doesn't have any "build" process (php) We rather need to test integration. Ins't Docker for that?  
> **username_1**: It's quite difficult to do the development inside docker. Generally teams develop in their local machines, push to git, CI process ensures that everything is fine and CI takes place on uniform system. Docker is certainly not for development from scratch but for packaging the already developed code  
> **username_0**: why so? I find quite easy to setup with docker different environments  whit different os, stacks and versions to test performance, upgrades etc. Why do you see Docker "certainly NOT" for development? I can also give a docker file or an image to a new developer and setup everything immediately.  

---

### Answer by username_2 on 2019-03-23. Score: 1

Here two parts: use IaC tools like Terraform to create environments and use Docker to deploy applications.

1) You can use Terraform with workspaces to make production and development. Maybe use Packer to prepare AMI images to reduce time for building.

2) Decide what CI/CD pipeline you will use to deploy apps. And first of all here you should know what orchestration tool you will use for Docker containers - compose, swarm, nomad, kubernetes.


---

### Answer by username_3 on 2019-02-08. Score: 0

If I understand your need:

* Need Infrastructure as Code.
* Configuration management.

Terraform is a great tool for creating your infrastructure. It has API support for AWS, GCP and almost all the cloud providers. Now that your infrastructure is ready, you need to configure the same using tools like (CHEF, Ansible or Puppet). I have personally bootstrapped the nodes created by Terraform to CHEF and have run cookbooks.

> **Comments:**
> **username_0**: Ok I understand that I provide the infrastructure with terraform and "provide"  the machines with something like Ansible. But I'm think already about using Docker for local development, to test machine upgrades and environments. So I guess I must repeat the Dockerfile instructions almost the same for Ansible when I deploy?  
> **username_3**: What about trying with Vagrant? Docker files is also an option, but how do we network between the container , Docker-compose?  

---

