Terraform Link: https://www.terraform.io/intro/getting-started/install.html
Setup your aws access keys: http://bit.ly/2vfkr4C
The file name format for terraform configuration files is *.tf, Terraform loads all configurations ending in *.tf, so it's better to put the file in a separate directory.
The provider section which is the cloud platform, in this case AWS. you can insert access keys directly into the configuration, but this is not good practice and not a secure way to use access keys.
Having setup your aws access credentials using "aws configure". You're ready to create a configuration file, some assumptions are made, you have a default VPC, and the default region is us-east-1, the ami-<numbers> change per region, so change this for the one for your region.
$ mkdir test
$ vi test.tf
Add the following code and save the file.
resource "aws_instance" "test" {
ami = "ami-aa5ebdd2"
instance_type = "t2.micro"
}
The resource can be logical or physical. In this case it's an EC2 instance which I have name "test". Test is a unique name for your terraform to identify it, you can call it joebloggs if you want, but ideally something to relate it to the purpose.
The resource can have a number of parameters, here there's only two the AMI ID and the type of instance you're creating. The AMI ID changes so it is best to get the id from AWS console or cli.
Initialize the environment for your configuration. This also download the the provider binary.
$ terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (0.1.4)...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = "~> 0.1"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Next you see what the terraform configuration will do before it does it. The + aws_instance.example, tells you it will add this. All the computed values are not known until the resource has been built.
$ terraform plan
provider.aws.region
The region where AWS operations will take place. Examples
are us-east-1, us-west-2, etc.
Default: us-east-1
Enter a value: us-west-1
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.
Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.
+ aws_instance.example
ami: "ami-aa5ebdd2"
associate_public_ip_address: "<computed>"
availability_zone: "<computed>"
ebs_block_device.#: "<computed>"
ephemeral_block_device.#: "<computed>"
instance_state: "<computed>"
instance_type: "t2.micro"
ipv6_address_count: "<computed>"
ipv6_addresses.#: "<computed>"
key_name: "<computed>"
network_interface.#: "<computed>"
network_interface_id: "<computed>"
placement_group: "<computed>"
primary_network_interface_id: "<computed>"
private_dns: "<computed>"
private_ip: "<computed>"
public_dns: "<computed>"
public_ip: "<computed>"
root_block_device.#: "<computed>"
security_groups.#: "<computed>"
source_dest_check: "true"
subnet_id: "<computed>"
tenancy: "<computed>"
volume_tags.%: "<computed>"
vpc_security_group_ids.#: "<computed>"
Plan: 1 to add, 0 to change, 0 to destroy.
Now that we know what it is going to do, we actually do it.
$ terraform apply
provider.aws.region
The region where AWS operations will take place. Examples
are us-east-1, us-west-2, etc.
Default: us-east-1
Enter a value: us-west-2
aws_instance.example: Creating...
ami: "" => "ami-aa5ebdd2"
associate_public_ip_address: "" => "<computed>"
availability_zone: "" => "<computed>"
ebs_block_device.#: "" => "<computed>"
...
...
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
To confirm the resource was built run the following. It will show all the fields that were previously just <computed>
$ terraform show
This is just an example using an off the shelf ami, Hashicorp all have something called packer to create (baked images) custom images. With packer you can have a set of instance look the same, for frontend instance and another set of image for backend instances.