Configuring modules

Let's list the data we need to pass to the module:

  • Name of the application
  • VPC ID
  • Subnet ID

That should be sufficient for now. Update the module inside template.tf to look as follows:

module "mighty_trousers" { 
  source = "./modules/application" 
  vpc_id = "${aws_vpc.my_vpc.id}" 
  subnet_id = "${aws_subnet.public.id}" 
  name = "MightyTrousers" 
} 

Passing data like this is not enough, though. We need to define variables inside the module template. The thing is, our tempate.tf is a module itself, a special module named root module. That's what you saw on the last graph we drew--resources were coming from the root module. So, we were actually already using modules all this time, and every module, including the root module, can be configured with variables.

Note

We did not look much into Terraform variables in general till now, and most of the content on this topic is explained in Chapter 4, Storing and Supplying Configuration. For now, let's get a short introduction to them.

Variables are defined with the variable keyboard, followed by the variable name and optional default value inside curly braces:

variable number_of_servers { default = 1 } 

There are many ways to define variables, and there are multiple types of variables, but let's save our in-depth exploration for the next chapter. For now, let's add the following lines to the top of ./modules/application/application.tf file:

variable "vpc_id"    {} 
variable "subnet_id" {} 
variable "name"      {} 

To use the variable, you need to reference it via a special var keyword, as follows: ${var.my_variable}. Replace all the resource references with variables:

resource "aws_security_group" "allow_http" { 
  name = "${var.name} allow_http" 
  description = "Allow HTTP traffic" 
  vpc_id = "${var.vpc_id}" 
 
  ingress { 
    from_port = 80 
    to_port = 80 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
  }  
  egress { 
    from_port = 0 
    to_port = 0 
    protocol = "-1" 
    cidr_blocks = ["0.0.0.0/0"] 
  } 
}  
resource "aws_instance" "app-server" { 
  ami = "ami-9bf712f4" 
  instance_type = "t2.micro" 
  subnet_id = "${var.subnet_id}" 
  vpc_security_group_ids = ["${aws_security_group.allow_http.id}"] 
  tags { 
    Name = "${var.name}" 
  } 
} 

Now you should be able to run again via the terraform get command:

$> terraform get 
Get: file:///home/kshirinkin/work/packt-terraform-rewrites/modules/application

This created a symlink to your module inside the .terraform directory:

$> ls -la .terraform/modules 
total 12 
drwxr-xr-x. 2 kshirinkin kshirinkin 4096 Jan  3 16:08 . 
drwxr-xr-x. 3 kshirinkin kshirinkin 4096 Jan  3 16:08 .. 
lrwxrwxrwx. 1 kshirinkin kshirinkin   66 Jan  3 16:08 8a6e0ac9202efe2b1f0a69ae2d5138bb -> /home/kshirinkin/work/packt-terraform-rewrites/modules/application 

You should be able to run the terraform apply command now. Let's add a second module, just to verify that we are still doing things right:

module "crazy_foods" { 
  source = "./modules/application" 
  vpc_id = "${aws_vpc.my_vpc.id}" 
  subnet_id = "${aws_subnet.public.id}" 
  name = "CrazyFoods" 
} 

Run the terraform get and terraform plan commands, to check whether Terraform will do everything as expected and pay attention to this part of the output:

+ module.mighty_trousers.aws_security_group.allow_http 
    description:                          "Allow HTTP traffic" 
    name:                                 "MightyTrousers allow_http" 

Note

For non-local modules, in order to update the module, you need to pass -update flag to the terraform get command: terraform get -update. Otherwise, the latest version of the module won't be downloaded.

Note how name of the resource was built; it includes the module name and a module keyword. It doesn't mean that you can reference this module by this name though. Try to do it as follows:

module "crazy_foods" { 
  source = "./modules/application" 
  vpc_id = "${aws_vpc.my_vpc.id}" 
  subnet_id = "${aws_subnet.public.id}" 
  name = "CrazyFoods ${module.mighty_trousers.aws_security_group.allow_http.id}" 
} 

You will get an error saying * module.crazy_foods: missing dependency: module.mighty_trousers.output.aws_security_group.allow_http.id. You cannot simply reference resources inside module from outside the module. You have to use outputs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.163.58