Terraform - Docker Provider - How to force container to use static IP?

1,283 views
Skip to first unread message

Tapas Mishra

unread,
Sep 23, 2016, 11:54:06 AM9/23/16
to Terraform

Hi all, 

 

Now I am trying to learn terraform and started using it with docker container. I wanted to create a lamp stack. So the requirement is as below

  • MySQL - Separate container
    • Port - 3306 needs to forward to host 8080
  • PHP/Apache – Separate container  
    • Port – 80 needs to forward to host 8080
  • Nginx as Proxy - Separate container
    • Port – 80 need to forward to host 80

Below is my code for this :

vi main.tf

module "db_server_vm" {

  source    = "./module"

  server_name  = "db-server"

  servers      = "1"

}

 

module "app_server_vm" {

  source    = "./module"

  server_name  = "app-server"

  servers      = "1"

}

 

module "proxy_server_vm" {

  source    = "./module"

  server_name  = "proxy-server"

  servers      = "1"

}

 

vi module/docker_container.tf

 

variable "container_image" {

  type = "string"

  default = "containers.dev.int/redhat:6.7_latest"

}

 

resource "docker_container" "container" {

    image = "${var.container_image}"

    name = "${var.server_name}-${count.index}"

    hostname = "${var.server_name}"

    domainname = "example.int"

    count = "${var.servers}"

    must_run = true

    restart = "always"

    privileged = true

    env = ["env=test", "role=test"]

 

    command = ["/usr/sbin/sshd", "-D", "-o", "UseDNS=no", "-o", "PasswordAuthentication=yes", "-o", "UsePrivilegeSeparation=no", "-o", "UsePAM=no", "-o", "PidFile=/tmp/sshd.pid"]

}

 

Using the above I am able to create the container but now I am confused how to put a logic to forward the relevant ports to host vm. Again how to assign static IP to the containers? 

David Maze

unread,
Sep 23, 2016, 4:01:43 PM9/23/16
to Terraform
On Friday, September 23, 2016 at 11:54:06 AM UTC-4, Tapas Mishra wrote:

Now I am trying to learn terraform and started using it with docker container. I wanted to create a lamp stack. So the requirement is as below


Are you trying to do this to learn about Terraform, or Docker?  It sounds like your questions are more about Docker, and I'd strongly recommend trying to use some of the standard Docker tools (for this setup, especially Docker Compose).

Launching an sshd in a container is generally considered unusual.  Best practices are generally to have a container do exactly one thing, like run the database or the application or the reverse proxy, and not run random extra daemons.  You can always get into the container with docker exec.
 

Using the above I am able to create the container but now I am confused how to put a logic to forward the relevant ports to host vm.


In standard Docker, the docker run -p command-line option.  In Docker Compose, the "ports" block.  In Terraform, a "ports" block within a "docker_container" resource.
 

Again how to assign static IP to the containers?


IMHO you're much better off forgetting that containers have IP addresses.  Treat them as an alternate packaging of processes that happen to be running on the host.  When I use Terraform to launch things that involve Docker, I actually use a "null_resource" resource to launch Ansible, and Ansible launches whatever software I need on the system, which sometimes is a docker: block.

Ricardo

unread,
Feb 13, 2017, 2:05:49 PM2/13/17
to Terraform
Is there a way to assign a static ip to a container via terraform? I see I can add extra hosts, but is there a way to set the ip_address attribute?

David Maze

unread,
Feb 13, 2017, 2:45:50 PM2/13/17
to Terraform
On Monday, February 13, 2017 at 2:05:49 PM UTC-5, Ricardo wrote:
Is there a way to assign a static ip to a container via terraform? I see I can add extra hosts, but is there a way to set the ip_address attribute?


In my experience, wanting this is pretty unusual; you'd need a very customized Docker networking setup for it to start to make sense.  Between containers, if you're setting up a private bridge network, then you get inter-container Docker DNS; outside containers, the Docker host would need a bridge interface that can connect the outside network to the Docker-internal network, which is outside Terraform's scope to set up.  A much more typical path would be to use a "ports" block (like "docker run -p") to expose individual ports from individual processes.

If you do need a container's private IP address, which is typically unroutable and can't be accessed beyond its specific host, you could always access "${docker_container.foo.ip_address}" and pass that into other resources' provisioners, like other Terraform resources.

(I haven't found a super great use for the Terraform Docker provider yet, in any case.  If I've just provisioned an AWS host with Terraform, Ansible makes a better post-install provisioner; if I'm running absolutely locally, Docker Compose works fine; and we're starting to look at Kubernetes [and sort of Nomad but not really] for multi-host container management.  There's no way, given an "${aws_instance.foo.ip_address}", to point the Docker provider at an ssh connection specified in a provisioner block, or to dynamically point multiple copies of the provisioner at multiple just-provisioned hosts, which really limits its utility to me.)

Philip Nelson

unread,
Feb 16, 2017, 11:17:37 AM2/16/17
to Terraform
The ip address is from the host, not the container. The port could be from the container if you forward that to the host. This is just normal docker stuff. 

If you want a static ip, either make the host have a static ip, and a fixed host port in your docker config. Use Elastic IP if at AWS OR
setup a load balancer or reverse proxy that has a static ip and forward requests from that to your host OR
if you are running in AWS assign and ALB/ELB and associate with a route 53 dns name
Reply all
Reply to author
Forward
0 new messages