Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 43 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1,66 @@
# terraform-ansible-example
Quick start on how to provision with ansible inside terraform
# Overview
Quick start on how to provision with ansible using terraform (remote) state file.

## Project structure
* ansible - folder with ansible playbooks, inventories and configuration
* terraform - folder with terraform infrastructure files
* packer - folder with packer image definition

## Getting stated
Prepend environment for using ansible dynamic inventory with Amazon ec2:
```
$ pip install boto
$ chmod +x ansible/ec2.py
```
Of course, you'll need to have AWS credentials. By default you can find it in ~/.aws/credentials
```
You'll need to have AWS credentials. By default you can find it in ~/.aws/credentials:
```sh
$ cat ~/.aws/credentials
[default]
aws_access_key_id = <AWS_ACCESS_TOKEN>
aws_secret_access_key = <AWS_SECRET_ACCESS_KEY>
...
```

In file ansible/ec2.ini define your regions:
```
...
regions = eu-central-1
regions_exclude = us-gov-west-1, cn-north-1
...
Create the base AWS AMI using packer (if you don't have one in the storage):
```sh
$ cd packer
$ packer validate ubuntu-16.04-amd64-example.json
$ packer build ubuntu-16.04-amd64-example.json
```

## Usage
if you want just up example infrastructure you need set your variables in .tfvars files
If you want just to run example infrastructure, create terraform.tfvars file from template terraform.tfvars.example and set your variables:
```sh
$ cd ../terraform
$ cp terraform.tfvars.example terraform.tfvars
```
pub_key_path = "~/.ssh/express42.pub"
private_key_path = "~/.ssh/express42"
key_name = "astarostenko"
env = "astarostenko"
(Optional) Create backend.tf file from template and set your backend configs:
```sh
$ cp backend.tf.example backend.tf
```

Go to terraform folder and download all modules to .terraform folder (for local modules it just creates symlinks)
```
$ cd terraform
$ terraform get
Initialize terraform configuration:
```sh
$ terraform init
```

If your want to see plan of your own infrastructure

```
(Optional) Check the plan of your infrastructure:
```sh
$ terraform plan
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.

data.aws_ami.image: Refreshing state...
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.

+ null_resource.ansible_db

+ null_resource.ansible_web

+ module.db.aws_instance.db
...
...
...
Plan: 9 to add, 0 to change, 0 to destroy.

```
To create all resources and provision all services
```

Create all resources:
```sh
$ terraform apply
```
To delete all created resources

Provision services:
```sh
$ cd ../ansible
$ ansible-playbook -i dynamic_inventory.sh playbooks/db.yml -e env="your_env"
$ ansible-playbook -i dynamic_inventory.sh playbooks/web.yml -e env="your_env"
```

Delete all created resources:
```sh
$ terraform destroy
```
# Terraform structure

#### main.tf - contain general infrastructure description
We describe used provider, can create resources, call some modules, and can also define provision
action
We describe used provider, can create resources, call modules:
```
provider "aws" {
region = "${var.region}"
Expand Down Expand Up @@ -130,30 +106,28 @@ variable "list_var_name" {
}
```

Variables can be defined in
* variables.tf or any other .tf file
Variables can be defined in variables.tf or any other .tf file:
```
variable env {
description = "current environment (dev, prod, stage)"
default = "dev"
}
```
You can just create it but not define in .tf file, but then you'll need to define it anywhere
You can just create it but not define in .tf file, but then you'll need to define it anywhere:
```
variable "name" {}
```

* terraform.tfvars (default) or any other .tfvars file with flag -var-file
```
```sh
$ terraform plan \
-var-file="secret.tfvars" \
-var-file="production.tfvars"
```
* input argument to terraform with flag -var
```
```sh
$ terraform plan -var 'access_key=foo'
```

[More information about variables](https://www.terraform.io/docs/configuration/variables.html)

#### outputs.tf - define all important output data like variables
Expand Down Expand Up @@ -183,3 +157,7 @@ We can use module just like:
}
```
[More information about modules](https://www.terraform.io/docs/modules/index.html)

## Links:
* [Terraform documentation](https://www.terraform.io/docs/ "Terraform documentation")
* [Ansible documentation](https://docs.ansible.com/ansible/index.html "Ansible documentation")
2 changes: 1 addition & 1 deletion ansible/playbooks/db.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---

- hosts: aws_tag_Group=dev_db_cluster
- hosts: aws_tag_Group={{ env }}_db_cluster
gather_facts: false
become: yes

Expand Down
2 changes: 1 addition & 1 deletion ansible/playbooks/web.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---

- hosts: aws_tag_Group=dev_web_cluster
- hosts: aws_tag_Group={{ env }}_web_cluster
gather_facts: false
become: yes

Expand Down
5 changes: 5 additions & 0 deletions packer/install-python.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

sudo apt-get update
sudo apt-get install -y python-minimal
sudo rm -rf /var/lib/apt/lists/*
30 changes: 30 additions & 0 deletions packer/ubuntu-16.04-amd64-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"builders": [
{
"type": "amazon-ebs",
"region": "eu-central-1",
"source_ami": "ami-060cde69",
"instance_type": "t2.micro",
"ssh_username": "ubuntu",
"ami_name": "ubuntu-16.04-amd64-python2-{{timestamp}}",
"ami_description": "Ubuntu Xenial 16.04 amd64 with python2",
"associate_public_ip_address": true,
"ami_block_device_mappings": [
{
"device_name": "/dev/sdb",
"delete_on_termination": "true",
"volume_type": "gp2",
"volume_size": "10",
"encrypted": "false"
}
]
}
],
"provisioners": [
{
"type": "shell",
"script": "install-python.sh",
"pause_before": "10s"
}
]
}
3 changes: 2 additions & 1 deletion terraform/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ data "aws_ami" "image" {

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64*"]
values = ["ubuntu-16.04-amd64-python2*"]
}
owners = ["self"]
}
6 changes: 6 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ module "web" {
sg_ids = "${module.base_linux.sg_id}"
name = "${var.web_server_params["name"]}"
count = "${var.web_server_params["count"]}"
ebs_optimized = "${var.ebs_optimized}"
monitoring = "${var.monitoring}"
azs = ["${var.azs}"]
}

module "db" {
Expand All @@ -37,4 +40,7 @@ module "db" {
sg_ids = "${module.base_linux.sg_id}"
name = "${var.db_server_params["name"]}"
count = "${var.db_server_params["count"]}"
ebs_optimized = "${var.ebs_optimized}"
monitoring = "${var.monitoring}"
azs = ["${var.azs}"]
}
11 changes: 7 additions & 4 deletions terraform/modules/db/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
resource "aws_instance" "db" {
ami = "${var.ami}"
count = "${var.count}"
instance_type = "${var.instance_type}"
key_name = "${var.key_name}"
ami = "${var.ami}"
count = "${var.count}"
instance_type = "${var.instance_type}"
ebs_optimized = "${var.ebs_optimized}"
monitoring = "${var.monitoring}"
key_name = "${var.key_name}"
availability_zone = "${element(var.azs, count.index)}"

vpc_security_group_ids = [
"${var.sg_ids}",
Expand Down
13 changes: 13 additions & 0 deletions terraform/modules/db/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ variable private_key_path {
description = "Path to the private key used to connect to instance"
}

variable azs {
description = "Run the EC2 Instances in these Availability Zones"
type = "list"
}

variable env {
description = "Environment prefix"
}
Expand All @@ -23,6 +28,14 @@ variable instance_type {
default = "t2.micro"
}

variable ebs_optimized {
description = "Create EBS–Optimized Instances"
}

variable monitoring {
description = "Enable detailed monitoring for EC2 instances"
}

variable sg_ids {
description = "List of security groups ids"
}
Expand Down
11 changes: 7 additions & 4 deletions terraform/modules/web/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
resource "aws_instance" "web" {
ami = "${var.ami}"
count = "${var.count}"
instance_type = "${var.instance_type}"
key_name = "${var.key_name}"
ami = "${var.ami}"
count = "${var.count}"
instance_type = "${var.instance_type}"
ebs_optimized = "${var.ebs_optimized}"
monitoring = "${var.monitoring}"
key_name = "${var.key_name}"
availability_zone = "${element(var.azs, count.index)}"

vpc_security_group_ids = [
"${var.sg_ids}",
Expand Down
13 changes: 13 additions & 0 deletions terraform/modules/web/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ variable private_key_path {
description = "Path to the private key used to connect to instance"
}

variable azs {
description = "Run the EC2 Instances in these Availability Zones"
type = "list"
}

variable env {
description = "Environment prefix"
}
Expand All @@ -23,6 +28,14 @@ variable instance_type {
default = "t2.micro"
}

variable ebs_optimized {
description = "Create EBS–Optimized Instances"
}

variable monitoring {
description = "Enable detailed monitoring for EC2 instances"
}

variable sg_ids {
description = "List of security groups ids"
}
Expand Down
1 change: 1 addition & 0 deletions terraform/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub_key_path = "~/.ssh/express42.pub"
private_key_path = "~/.ssh/express42"
key_name = "astarostenko"
env = "astarostenko"

web_server_params {
count = "1"
Expand Down
16 changes: 16 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ variable region {
default = "eu-central-1"
}

variable ebs_optimized {
description = "Create EBS–Optimized Instances"
default = "false"
}

variable monitoring {
description = "Enable detailed monitoring for EC2 instances"
default = "false"
}

variable azs {
description = "Run the EC2 Instances in these Availability Zones"
type = "list"
default = ["eu-central-1a", "eu-central-1b"]
}

variable env {
description = "Environment prefix"
default = "dev"
Expand Down