In this lecture, let us create a new module in
terraform and then put it to use to deploy multiple environments
of the same infrastructure.
Let us assume that an organization called Flex IT
consulting has a blueprint of a prototype payroll
software that needs to be deployed in several countries.
Each country will have its own instance of the software deployed
on AWS Cloud using the same architecture.
It has a single ec2 instance using a custom Ami that
will hold the application server.
A dynamodb no SQL database that will be used to
store the employee and payroll data.
And then we have an S3 bucket, which will be used to
store documents such as pay stubs and tax forms.
Users access the application which is hosted on this ec2
instance.
This is an architecture in its most simplified form
that uses the default VPC and does not
consider things like VPC endpoints or I
am rules for the services.
The architecture diagram at a very high level looks like
this.
So the idea here is to create a reusable tefl
module and use it to deploy the same stack of
resources in different countries.
And based on this high level architecture. We can
create our configuration in a directory.
Since we plan to create a module we created under the
directory called modules. For instance. Let's use
of the path / root terraform projects /
modules.
This is where we plan to store all our reusable
modules.
Inside this we have the resource block
for all the required services such as the ec2 instance S3
bucket and dynamodb.
To ensure that we have consistent environments and
to use a specific instance type for all the
environments created by the module. The value of instance type
has been hard coded into the configuration file like
this.
Will soon see why this is done.
The Ami however is set to the variable called Ami
and is user configurable based on the region
where we want to deploy the application. Same goes
for the tag call name here. We are
making use of an interpolation expression to use the value
of name which depends on the region where we
want to deploy this application.
Also note that an explicit dependency is defined
in the ec2 resource block to ensure that it
is only created after the dynamodb and the S3
buckets are provisioned.
And the same goes for the S3 bucket name to ensure
that we have a globally unique name for the bucket. We are
adding the region as a prefix for the bucket name.
Finally the dynamodb name and the primary key
for the table have also been assigned fixed values.
Please note that to improve the readability the configuration
files that you see here have been truncated.
And a variables for this configuration would look like
this the variables called app underscore region
and Ami just have the variable type defined in
the block.
The variable called bucket. However has a
default value assigned to it as well.
These variables have been used in the configuration files
that we just saw.
Now, let's deploy an instance of this application stack
first in the US each one
region.
To do this. Let us create another directory called us
payroll app and inside this directory. We
create a main.tf file with the contents like this.
Here we will make use of the module block and specify the
path to the payroll app module that we created earlier.
To make sure that we deploy to the US East one
region and use the custom Ami ID in
that region. We can specify the app underscore region
and the Ami in a root module like this.
And that's it. Since this is our working configuration
directory the path / root slash terraform
project / us payroll app
is now the root module and the modules directory
which is modules / payroll app,
which is used as the source is the child module.
You would have noticed that the only configurable value in
this main.ta file is the app region and
the Ami ID.
We can also optionally provide a specific value for the bucket argument.
But if it is not it'll take the default value
that was set at the module level which in this case is flexit
- payroll Dash Alpha -
22001c
We do not want the instance type the Dynamo DB name
and the primary key to change and this is why we have hardcore
to the values in the module configuration.
With just this module block. Our configuration file is
now complete and ready to be applied.
If you enter from in it now, we'll see
that terraform downloads the module from Source along with
the AWS plugin, which is used by that module.
A plan followed by apply will show that the dynamodb table
the S3 bucket and the AWS ec2
instance are created.
Observe that the dynamodb table name the primary key and
the instance type for the ec2 instance take values
that we have defined at the child module.
The bucket name and the Ami ID on
the other hand makes use of the values that we have defined in
the root module.
To deploy the same stack in the UK region. Let's create
another directory called UK payroll app.
We then follow the same process of creating a main.tf file
and then make use of the same module block inside this
module block. We use the value of Euless 2
for the app region. We have also changed the Ami ID
to select the one that's available in this region.
Running the terraform workflow now will create
the exact same stack but in the London region.
Notice that the name of the S3 bucket created now
has the prefix of EU waste 2.
Since we are making
use of a module the dynamodb table resource
that has been created is now identified by the addressing
syntax that goes like this.
First comes the module address, which is the keyword
module followed by the module name, which is
separated by a DOT.
Next comes the resource address, which is the resource type followed by
the resource name also separated by a DOT.
So in this example the dynamodb table resource in
the root module can be addressed as module dot us
payroll dot AWS dynamodb table
dot payroll DB.
We have now successfully created a terraform module
and use it to deploy multiple instances of our application
in different regions.
Modules are comparable to libraries or
packages that are used in most programming languages.
This brings in a lot of benefits such as simpler configuration
instead of having configuration files that
contain hundreds and thousands of lines of code.
Our root module now is very short easy to
understand and manage.
Using a pre-configured module that has been tested and validated
also decreases the risk of human errors resulting
in inconsistent environments.
As we just saw the same module can be used to deploy
the infrastructure in different regions. Thereby improving
the reusability of our code.
And finally by making sure that certain aspects of
our configuration are fixed such as the dynamodb table
name the primary key and the instance type which are
not user configurable from the root module. We can
make sure that the provisioning process maintains a standard configuration.
That's it for this lecture in the next one. We'll see how to make
use of modules from the public terraform registry.