Terraform/Terragrunt — Пишем модуль. Часть 1

В данном примере мы создадим Terraform модуль для провайдера AWS, который будет запускаться для 3-х разных окружений при помощи Terragrunt'a.

 

Требования:

 

Создадим обязательные файлы для Terragrunt'а:

terragrunt.hcl

terraform {
  extra_arguments "custom_vars" {
    commands = get_terraform_commands_that_need_vars()
    arguments = [
      "-var-file=${get_terragrunt_dir()}/common.tfvars",
    ]
  }
}

remote_state {
  backend = "s3"
  config = {
    bucket         = "tfstate.eu-west-2.artem"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "eu-west-2"
    encrypt        = true
    dynamodb_table = "my-lock-table"
  }
}

 

Зададим имя S3 корзины, которая будет хранить состояние Terragrunt'а, создавать ее предварительно не нужно, Terragrunt создаст ее сам. Так же зададим регион.

Создадим файл для хранения переменных Terraform'а и Terragrunt'а:

touch common.tfvars variables.tf

 

Напишем первый модуль, который будет создавать VPC и Internet Gateway для него.

 

Создаем директорию для модулей и для VPC в частности:

mkdir -p modules/vpc

 

Модули работают по принципу функции, при обращении к ним мы передаем ряд переменных.

Для создания VPC нам нужно знать следующее:

  • Имя VPC
  • CIDR

 

Создадим отдельный файл для переменных "modules/vpc/variables.tf" и добавим туда следующее:

variable "vpc_name" {}
variable "vpc_cidr" {}

 

Создаем сам модуль, для этого создаем файл "modules/vpc/main.tf" со следующим содержимым:

#################### CREATE VPC ####################

resource "aws_vpc" "vpc" {
  cidr_block = var.vpc_cidr
  enable_dns_hostnames = "true"
  enable_dns_support = "true"

  tags = {
    Name = var.vpc_name
  }
}
 
############# CREATE INTERNET GATEWAY ##############

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id
 
  tags = {
    Name = "${var.vpc_name}-IGW"
  }
}

 

Мы будем создавать шаблон для трех разных окружений:

  • development
  • staging
  • production

 

Заполним файл переменных для Terragrunt'а:

common.tfvars

### DEVELOPMENT ENVIRONMENT ####

development_aws_region = "us-east-1"
development_vpc_name = "ARTEM-DEVELOPMENT-USE1"
development_vpc_cidr = "192.168.0.0/16"

######### END OF BLOCK #########

##### STAGING ENVIRONMENT ######

staging_aws_region = "us-east-1"
staging_vpc_name = "ARTEM-STAGING-USE1"
staging_vpc_cidr = "192.168.0.0/16"

######### END OF BLOCK #########

#### PRODUCTION ENVIRONMENT ####

production_aws_region = "eu-central-1"
production_vpc_name = "ARTEM-PRODUCTION-EUC1"
production_vpc_cidr = "192.168.0.0/16"

######### END OF BLOCK #########

 

Теперь заполним файл переменных Terraform'а:

variables.tf

### DEVELOPMENT ENVIRONMENT ####

variable "development_aws_region" {}
variable "development_vpc_name" {}
variable "development_vpc_cidr" {}

######### END OF BLOCK #########

##### STAGING ENVIRONMENT ######

variable "staging_aws_region" {}
variable "staging_vpc_name" {}
variable "staging_vpc_cidr" {}

######### END OF BLOCK #########

#### PRODUCTION ENVIRONMENT ####

variable "production_aws_region" {}
variable "production_vpc_name" {}
variable "production_vpc_cidr" {}

######### END OF BLOCK #########

 

Мы готовы к созданию первой среды, начнем с development среды

Создаем структуру:

mkdir -p environments/development

 

Перейдем в созданную директорию:

cd environments/development

 

Создадим обязательный файл "terragrunt.hcl" и вставим в него следующее:

include {
  path = find_in_parent_folders()
}

 

И создадим символические ссылки на файлы переменных, находящиеся в корне:

ln -s ../../variables.tf variables.tf
ln -s ../../common.tfvars common.tfvars

 

Создадим файл "main.tf" со следующим содержимым:

terraform {
  backend "s3" {}
}

provider "aws" {
  region  = var.development_aws_region
}

 

Все, теперь можно создавать файл Terraform'а для вызова модуля для создания VPC.

 

vpc.tf

module "vpc" {
  source        = "../../modules/vpc"
  vpc_name      = var.development_vpc_name
  vpc_cidr      = var.development_vpc_cidr
}

 

Выполняем:

terragrunt init

 

При первом запуске Terragrunt скажет, что корзины для хранения состояний не существует, и предложит создать ее, соглашаемся.

После init'а, смотрим версию Terraform'а и AWS провайдера, лучше эти версии указать в файле "main.tf", если планируется запуск с другого компьютера (так как мы создаем корзину для хранения состояния, то мы и подразумеваем запуск с любого компьютера с сохранением текущего состояния)

terraform --version
Terraform v0.12.9
+ provider.aws v2.30.0

 

main.tf

terraform {
  backend "s3" {}
  required_version = "~> 0.12.9"
}

provider "aws" {
  region  = var.development_aws_region
  version = "~> 2.30"
}

 

Теперь по образу development среды, создадим staging и production. Возвращаемся в корень проекта, удаляем директорию ".terraform" в "envarinments/development" и копируем development среду:

rm -rf environments/development/.terraform/
cp -aR environments/development environments/staging
cp -aR environments/development environments/production

 

Меняем переменные для staging'а:

sed -i 's/development/staging/g' environments/staging/{main.tf,vpc.tf}

 

Меняем переменные для production'а:

sed -i 's/development/production/g' environments/production/{main.tf,vpc.tf}

 

Теперь находясь в корне проекта можем запустить планировку для все окружений одной командой:

terragrunt plan-all

 

Применить данный теймплейт можно как для каждой среды в частности, находясь в директории необходимой среды выполнить:

terragrunt apply

 

Или же для всех сразу, находясь в корне проекта выполнить:

terragrunt apply-all

 

Финальная наша структура выглядит следующим образом:

.
├── common.tfvars
├── environments
│   ├── development
│   │   ├── common.tfvars -> ../../common.tfvars
│   │   ├── main.tf
│   │   ├── terragrunt.hcl
│   │   ├── variables.tf -> ../../variables.tf
│   │   └── vpc.tf
│   ├── production
│   │   ├── common.tfvars -> ../../common.tfvars
│   │   ├── main.tf
│   │   ├── terragrunt.hcl
│   │   ├── variables.tf -> ../../variables.tf
│   │   └── vpc.tf
│   └── staging
│       ├── common.tfvars -> ../../common.tfvars
│       ├── main.tf
│       ├── terragrunt.hcl
│       ├── variables.tf -> ../../variables.tf
│       └── vpc.tf
├── modules
│   └── vpc
│       ├── main.tf
│       └── variables.tf
├── terragrunt.hcl
└── variables.tf

6 directories, 20 files

 

Для того, чтобы хранить наш шаблон в репозитории, в файл ".gitignore" добавим следующее:

.terraform/
terraform.*

 

Данный пример можно скачать Git репозиторием:

https://bitbucket.org/artem-gatchenko/example-terraform-module-part1
0 0 vote
Рейтинг статьи

Метки: Метки

Подписаться
Уведомление о
guest
0 комментариев
Inline Feedbacks
View all comments