ããã¯ããªã«ãããããŠæžãããã®ïŒ
TerragruntãåŠã¶ã·ãªãŒãºã
次ã¯ãTerragruntã䜿ã£ãŠTerraformå®è¡æã®åŒæ°ããªãã·ã§ã³æå®ããŸãšããŠã¿ãŸãã
Terragruntã§ãTerraformå®è¡æã®åŒæ°ããªãã·ã§ã³æå®ããŸãšãã
Terraformãå®è¡ããæã«ãåŒæ°ããªãã·ã§ã³ãæå®ããããšããããŸãã
ããšãã°å
±éã®å€æ°ã®å€ãèšå®ãããã¡ã€ã«ãå Žåã¯ãTerraformã¢ãžã¥ãŒã«ã®å®è¡ããšã«-var-file
ãªãã·ã§ã³ãä»ããããšã«
ãªããŸãããŸããapply
æã«ãã€ãããã¯ã®ã¿ã€ã ã¢ãŠãã®èšå®ãæå®ãããå Žåã¯ãæ¯å-lock-timeout
ãæå®ããããšã«
ãªããŸãã
â» terraform.tfvars
ãã¡ã€ã«ãåã¢ãžã¥ãŒã«ãã£ã¬ã¯ããªã«äœæããã°-var-file
ã®æå®ã¯èŠããªããšãã話ããããŸããããã®å Žåã¯
ã 䌌ãå
容ã®ãã¡ã€ã«ããã©ãŸãããããšã«ãªããŸããâŠ
Quick start / Keep your Terraform CLI arguments DRY
Terragruntã䜿ããšãterragrunt.hcl
ã«ãããã®å®çŸ©ããŸãšããããšãã§ããããã§ãã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã§ãã
$ terraform version Terraform v0.14.7 $ terragrunt -v terragrunt version v0.28.7
Terraform Providerã¯ãMySQLçšã®ãã®ã䜿çšããŸãã
Provider: MySQL - Terraform by HashiCorp
䜿çšããMySQLã¯8.0.23ãšãã172.17.0.2ã§åäœããŠãããã®ãšããŸãã
ãé¡
MySQL Providerã䜿ãã以äžã®ãªãœãŒã¹ãå®çŸ©ãã2ã€ã®Terraformã«ãŒãã¢ãžã¥ãŒã«ãäœæããŸãã
- ããŒã¿ããŒã¹
- ãŠãŒã¶ãŒããã³æš©é
ãã®æã«æå®ããProviderã®å®çŸ©ãããŒã¿ããŒã¹åãå€æ°åãããããæå®ãããªãã·ã§ã³ããŸãšããŠã¿ãŸãããã
â» Terragruntã䜿ããšProviderã®å®çŸ©ããŸãšããããšãã§ããŸãããä»åã¯ãªãã·ã§ã³ã®è©±ã«çµããŸã
æåã¯Terragruntã䜿ããã«Terraformã§æ¯åãªãã·ã§ã³ãæå®ãããã®åŸã«Terragruntã§æå®ãããªãã·ã§ã³ããŸãšããŠã¿ãŸãããã
Terragruntã䜿ããªãå Žå
ãŸãã¯ãTerragruntã䜿ããã«ããŒã¹ãäœã£ãŠãããŸãã
ããŒã¿ããŒã¹ããŠãŒã¶ãŒããã³æš©éçšã«2ã€ã®ãã£ã¬ã¯ããªãäœæã
$ mkdir database users
ä»åã¯ãããããæãã®æ§æã«ããŸããã
$ tree . âââ database â  âââ main.tf â  âââ variables.tf âââ database.tfvars âââ provider.tfvars âââ users âââ main.tf âââ variables.tf 2 directories, 6 files
MySQL Providerã䜿ãã®ã§æ¥ç¶å
ã®å®çŸ©ãå¿
èŠãªã®ã§ãããããã¯tfvars
ãã¡ã€ã«ã«ãŸãšããŠãããŸãã
provider.tfvars
mysql_provider_endpoint = "172.17.0.2:3306" mysql_provider_username = "root" mysql_provider_password = "password"
ãŸããäœæããããŒã¿ããŒã¹ãæš©éèšå®ã«é¢ããããŒã¿ããŒã¹åãtfvars
ãã¡ã€ã«ã«ãŸãšããŠãããŸãããã
database.tfvars
database_name = "my_database"
ããŒã¿ããŒã¹åŽã®ã¢ãžã¥ãŒã«å®çŸ©ã«ç§»åããŸãã
$ cd database
ãªãœãŒã¹å®çŸ©ã¯ããããªæãã§çšæãProviderå®çŸ©ãããŒã¿ããŒã¹åã¯å€æ°åããŠããŸãã
main.tf
terraform { required_version = "0.14.7" required_providers { mysql = { source = "terraform-providers/mysql" version = "1.9.0" } } } provider "mysql" { endpoint = var.mysql_provider_endpoint username = var.mysql_provider_username password = var.mysql_provider_password } resource "mysql_database" "app" { name = var.database_name default_character_set = "utf8mb4" default_collation = "utf8mb4_ja_0900_as_cs_ks" } output "database_name" { value = mysql_database.app.name }
å€æ°å®çŸ©ã
variables.tf
variable "mysql_provider_endpoint" { type = string } variable "mysql_provider_username" { type = string } variable "mysql_provider_password" { type = string } variable "database_name" { type = string }
init
ããŠ
$ terraform init
äžäœã®ãã£ã¬ã¯ããªã«ããtfvars
ãã¡ã€ã«ãæå®ããŠapply
ã
$ terraform apply -var-file=../provider.tfvars -var-file=../database.tfvars
ãªãœãŒã¹ãã§ããŸããã
mysql_database.app: Creating... mysql_database.app: Creation complete after 0s [id=my_database] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: database_name = "my_database"
ãŠãŒã¶ãŒããã³æš©éåŽã
$ cd ../users
ãã¡ãã®ãªãœãŒã¹å®çŸ©ã¯ããããªæãã§ããããŒã¿ããŒã¹å®çŸ©ãšåãããProviderå®çŸ©ãšããŒã¿ããŒã¹åã«é¢ããéšåãå€æ°ã«
ãªã£ãŠããŸãã
main.tf
terraform { required_version = "0.14.7" required_providers { mysql = { source = "terraform-providers/mysql" version = "1.9.0" } } } provider "mysql" { endpoint = var.mysql_provider_endpoint username = var.mysql_provider_username password = var.mysql_provider_password } resource "mysql_user" "admin_user" { user = "admin" plaintext_password = "password" host = "%" } resource "mysql_grant" "admin_user" { user = mysql_user.admin_user.user host = mysql_user.admin_user.host database = var.database_name privileges = ["ALL"] } resource "mysql_user" "application_user" { user = "appuser" plaintext_password = "password" host = "%" } resource "mysql_grant" "application_user" { user = mysql_user.application_user.user host = mysql_user.application_user.host database = var.database_name privileges = ["SELECT", "INSERT", "UPDATE", "DELETE"] } output "admin_user_name" { value = mysql_user.admin_user.user } output "admin_user_privileges" { value = mysql_grant.admin_user.privileges } output "app_user_name" { value = mysql_user.application_user.user } output "app_user_privileges" { value = mysql_grant.application_user.privileges }
å€æ°å®çŸ©ã¯ãããŒã¿ããŒã¹å®çŸ©ã®æãšåãã§ããã
variables.tf
variable "mysql_provider_endpoint" { type = string } variable "mysql_provider_username" { type = string } variable "mysql_provider_password" { type = string } variable "database_name" { type = string }
init
ããŠ
$ terraform init
ãã£ã±ãtfvars
ãã¡ã€ã«ãæå®ããŠapply
ã
$ terraform apply -var-file=../provider.tfvars -var-file=../database.tfvars
ãªãœãŒã¹ãäœæãããŸããã
mysql_user.admin_user: Creating... mysql_user.application_user: Creating... mysql_user.admin_user: Creation complete after 0s [id=admin@%] mysql_grant.admin_user: Creating... mysql_user.application_user: Creation complete after 0s [id=appuser@%] mysql_grant.application_user: Creating... mysql_grant.admin_user: Creation complete after 0s [id=admin@%:`my_database`] mysql_grant.application_user: Creation complete after 0s [id=appuser@%:`my_database`] Apply complete! Resources: 4 added, 0 changed, 0 destroyed. Outputs: admin_user_name = "admin" admin_user_privileges = toset([ "ALL", ]) app_user_name = "appuser" app_user_privileges = toset([ "DELETE", "INSERT", "SELECT", "UPDATE", ])
ãããŸã§ã§ã1床ãªãœãŒã¹ãç Žæ£ããŠäžäœãã£ã¬ã¯ããªã«æ»ããŸããããdestroy
æããtvfars
ã®æå®ãå¿
èŠã§ããã
$ terraform destroy -var-file=../provider.tfvars -var-file=../database.tfvars $ cd ../database $ terraform destroy -var-file=../provider.tfvars -var-file=../database.tfvars $ cd ..
Terragruntã䜿ã£ãŠããªãã·ã§ã³æå®ããŸãšãã
ãããŸã§ã§ãapply
ãdestroy
æã«åããªãã·ã§ã³ãæ¯åæå®ããŠããŸãããProviderå®çŸ©ã®ããã«ãå
±éã«äœ¿ããã®ãããã®ã§
ããããã®ã¯ç¢ºå®ã«åããªãã·ã§ã³ãè€æ°ã®Terraformã¢ãžã¥ãŒã«ã§æå®ããããšã«ãªããŸããã
ã§ãTerragruntã䜿ã£ãŠãããããªãã·ã§ã³æå®ããŸãšããã«ã¯ãterragrunt.hcl
ãã¡ã€ã«ãäœæããŠã以äžã®ããã«èšè¿°ããŸãã
terragrunt.hcl
terraform { extra_arguments "common_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var-file=../provider.tfvars", "-var-file=../database.tfvars" ] } }
terraform
ãããã¯å
ã«ãextra_arguments
ãšãããããã¯ãå®çŸ©ããŸãã
extra_arguments
ã¯ãTerraformã®CLIã«æå®ããåŒæ°ãå®çŸ©ããããã®ãããã¯ã§ãã
åŒæ°ããªãã·ã§ã³ä»¥å€ã«ããç°å¢å€æ°ã®èšå®ãå¿
é ãšãªãtfvars
ãã¡ã€ã«ããªãã·ã§ã³ã®ïŒååšããã°äœ¿ãïŒã®tfvars
ãã¡ã€ã«ã®
èšå®ãªã©ãã§ããããã§ãã
get_terraform_commands_that_need_vars
ãšããã®ã¯ãTerragruntã®çµã¿èŸŒã¿é¢æ°ã§ããVariablesã䜿ãå¯èœæ§ãããã³ãã³ãã
è¿ããŸãã
Built-in functions / get_terraform_commands_that_need_vars
å®çŸ©ã¯ãã¡ãã
https://github.com/gruntwork-io/terragrunt/blob/v0.28.7/config/config_helpers.go#L113
https://github.com/gruntwork-io/terragrunt/blob/v0.28.7/config/config_helpers.go#L38-L47
ã€ãŸãããã¡ãã®å®çŸ©ã¯
commands = get_terraform_commands_that_need_vars()
以äžãšå矩ã«ãªããŸãã
commands = ["apply", "console", "destroy", "import", "plan", "push", "refresh"]
ä»åã¯-var-file
ã®ã¿ã®æå®ã«ããŠããŸãããä»ã«ãªãã·ã§ã³ãæå®ããããã³ãã³ãããšã«çŽ°ããåããããšãã£ãäŸã
ããã¥ã¡ã³ãã«æžãããŠããŸãã
次ã«ãããŒã¿ããŒã¹ã®ã¢ãžã¥ãŒã«å®çŸ©ãžç§»åã
$ cd database
terragrunt.hcl
ãã¡ã€ã«ãäœæããŸããå
容ã¯ãäžäœãã£ã¬ã¯ããªã«ããterragrunt.hcl
ãåç
§ããã ãã§ãã
terragrunt.hcl
include { path = find_in_parent_folders() }
ããã§ãterragrunt
ã³ãã³ãã䜿ãå Žåã¯ãªãã·ã§ã³æå®ãªãã§plan
ãªã©ãå®è¡ã§ããããã«ãªããŸãã
$ terragrunt plan An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # mysql_database.app will be created + resource "mysql_database" "app" { + default_character_set = "utf8mb4" + default_collation = "utf8mb4_ja_0900_as_cs_ks" + id = (known after apply) + name = "my_database" } Plan: 1 to add, 0 to change, 0 to destroy. Changes to Outputs: + database_name = "my_database" ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
tfvars
ã§å®çŸ©ããå
容ãè£å®ãããŠããŸãããã€ãŸãã以äžãšå矩ã®ç¶æ
ã«ãªã£ãŠããŸãã
$ terraform plan -var-file=../provider.tfvars -var-file=../database.tfvars
åæ§ã«apply
ããªãã·ã§ã³æå®ãªãã§å®è¡ã§ããŸãã
$ terragrunt apply
ãªãœãŒã¹ãäœæã§ããŸããã
mysql_database.app: Creating... mysql_database.app: Creation complete after 0s [id=my_database] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: database_name = "my_database"
ãŠãŒã¶ãŒãæš©éãå®çŸ©ããã¢ãžã¥ãŒã«ãžç§»åã
$ cd ../users
ãã¡ãããterragrunt.hcl
ãã¡ã€ã«ãäœæã
terragrunt.hcl
include { path = find_in_parent_folders() }
ããŒã¿ããŒã¹å®çŸ©ã®æãšåãããã«ããªãã·ã§ã³æå®ãªãã§apply
ã§ããããã«ãªããŸãã
$ terragrunt apply
ãªãœãŒã¹ãã§ããŸããã
mysql_user.application_user: Creating... mysql_user.admin_user: Creating... mysql_user.application_user: Creation complete after 0s [id=appuser@%] mysql_grant.application_user: Creating... mysql_user.admin_user: Creation complete after 0s [id=admin@%] mysql_grant.admin_user: Creating... mysql_grant.application_user: Creation complete after 0s [id=appuser@%:`my_database`] mysql_grant.admin_user: Creation complete after 0s [id=admin@%:`my_database`] Apply complete! Resources: 4 added, 0 changed, 0 destroyed. Outputs: admin_user_name = "admin" admin_user_privileges = toset([ "ALL", ]) app_user_name = "appuser" app_user_privileges = toset([ "DELETE", "INSERT", "SELECT", "UPDATE", ])
destroy
ããªãã·ã§ã³ãèŠããªããªããŸãã
$ terragrunt destroy $ cd ../database $ terragrunt destroy $ cd ..
ããã§ãTerragruntã䜿ã£ãŠãªãã·ã§ã³æå®ããŸãšããããšã確èªã§ããŸããã
è€æ°ã®extra_argumentsãå®çŸ©ãã
å
ã»ã©ã¯extra_arguments
ãã²ãšã€å®çŸ©ããŠäœ¿ããŸããããè€æ°å®çŸ©ããããšãã§ããŸãã
ããŸãæå³ã¯ãããŸããããProviderã«é¢ããtfvars
ãã¡ã€ã«ãæå®ãããšextra_arguments
ãããŒã¿ããŒã¹åã«é¢ãã
extra_arguments
ã«åå²ããŠã¿ãŸãã
å°ãå€åãå
¥ãããããããŒã¿ããŒã¹åã«é¢ããŠã¯-var
ã§æå®ããããã«ããŠã¿ãŸããããšãã£ãŠããtfvars
ã§æå®ããŠãã
å
容ãšåãã§ããâŠã
terragrunt.hcl
terraform { extra_arguments "provider_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var-file=../provider.tfvars" ] } extra_arguments "database_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var", "database_name=my_database" ] } }
å®éã®ã¢ãžã¥ãŒã«é©çšåŽã§ã¯ããã®å€æŽãæèããããšãªã䜿ãããšãã§ããŸãã
ããŒã¿ããŒã¹åŽã
$ cd database $ terragrunt apply
確èªã
mysql_database.app: Creating... mysql_database.app: Creation complete after 0s [id=my_database] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: database_name = "my_database"
ãŠãŒã¶ãŒããã³æš©éåŽã
$ cd ../users $ terragrunt apply
確èªã
mysql_user.admin_user: Creating... mysql_user.application_user: Creating... mysql_user.application_user: Creation complete after 0s [id=appuser@%] mysql_grant.application_user: Creating... mysql_user.admin_user: Creation complete after 0s [id=admin@%] mysql_grant.admin_user: Creating... mysql_grant.application_user: Creation complete after 0s [id=appuser@%:`my_database`] mysql_grant.admin_user: Creation complete after 0s [id=admin@%:`my_database`] Apply complete! Resources: 4 added, 0 changed, 0 destroyed. Outputs: admin_user_name = "admin" admin_user_privileges = toset([ "ALL", ]) app_user_name = "appuser" app_user_privileges = toset([ "DELETE", "INSERT", "SELECT", "UPDATE", ])
ããã«ãªãã·ã§ã³ãæå®ãããšïŒ
ãšããã§ãåŒæ°ããªãã·ã§ã³å®çŸ©ãæå®ããç¶æ ã§ãåããªãã·ã§ã³ãæå®ãããšã©ããªãã®ã§ãããïŒ
terragrunt.hcl
ããã®ç¶æ
ã§
terragrunt.hcl
terraform { extra_arguments "provider_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var-file=../provider.tfvars" ] } extra_arguments "database_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var", "database_name=my_database" ] } }
ããŒã¿ããŒã¹ã®ã¢ãžã¥ãŒã«åŽã§ã-var
ãæå®ããŠplan
ãå®è¡ããŠã¿ãŸãã
$ cd database $ terragrunt plan -var database_name=foo An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # mysql_database.app will be created + resource "mysql_database" "app" { + default_character_set = "utf8mb4" + default_collation = "utf8mb4_ja_0900_as_cs_ks" + id = (known after apply) + name = "foo" } Plan: 1 to add, 0 to change, 0 to destroy. Changes to Outputs: + database_name = "foo" ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
terragrunt
ã³ãã³ãå®è¡æã«æå®ããå
容ã§ãplan
ãå®è¡ãããŸããâŠããããã¯ä»¥äžã®ããã«è§£éãããŠãããšèããã¹ã
ã§ããããã
$ terraform plan -var-file=../provider.tfvars -var database_name=my_database -var database_name=foo
å°ãªããšãããŸãšãããªãã·ã§ã³ãšåããã®ãã³ãã³ãå®è¡æã«æ¹ããŠæå®ããªãæ¹ãè¯ãæ°ãããŸãã
ã¢ãžã¥ãŒã«åºæã®å 容ãæå®ãããå ŽåïŒ
ä»åã¯åã¢ãžã¥ãŒã«å®è¡æã«æå®ãããªãã·ã§ã³ãå
šéšåãã«ãŸãšããŸããããäžéšã¯ã¢ãžã¥ãŒã«åäœã§åºæã«æå®ããšãã£ã
ããšã¯ã§ããã®ã§ããããã
ããšãã°ãããããã£ã¬ã¯ããªã«ããterragrunt.hcl
ãã¡ã€ã«ã¯ä»¥äžã®Providerã«é¢ããtfvars
ãã¡ã€ã«ãæå®ããã ãã«ããŠã¿ãŸãã
terragrunt.hcl
terraform { extra_arguments "provider_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var-file=../provider.tfvars" ] } }
ããŒã¿ããŒã¹ã®å®çŸ©ãžç§»åã
$ cd database
ãã®æç¹ã§ã¯ãããŒã¿ããŒã¹åŽã®ã¢ãžã¥ãŒã«ãå®è¡ããã«ã¯ããŒã¿ããŒã¹åã®æå®ã足ããªãç¶æ ã§ãã
ããã§ãterragrunt.hcl
ãã¡ã€ã«ãäžäœãã£ã¬ã¯ããªã®å
容ãåç
§ããã ãã§ãªããåºæã®extra_arguments
ãæã€ããã«å€ããŠã¿ãŸãã
terragrunt.hcl
include { path = find_in_parent_folders() } terraform { extra_arguments "database_vars" { commands = get_terraform_commands_that_need_vars() arguments = [ "-var", "database_name=my_database" ] } }
plan
ã§ç¢ºèªããŠã¿ãŸãã
$ terragrunt plan An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # mysql_database.app will be created + resource "mysql_database" "app" { + default_character_set = "utf8mb4" + default_collation = "utf8mb4_ja_0900_as_cs_ks" + id = (known after apply) + name = "my_database" } Plan: 1 to add, 0 to change, 0 to destroy. Changes to Outputs: + database_name = "my_database" ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
èªèããŠããããã§ãããOKã§ãã
ããããæãã§ãã¢ãžã¥ãŒã«ãè·šãã§æå®ãããªãã·ã§ã³ã ãã§ãªããTerraformå®è¡æã«æå®ãããªãã·ã§ã³ãå¿ããªãããã«
å®çŸ©ããå ŽãšããŠã䜿ãããã§ããã
ãŸãšã
Terragruntã䜿ã£ãŠãTerraformã®åŒæ°ããªãã·ã§ã³ããŸãšããŠã¿ãŸããã
æå®ãããªãã·ã§ã³ãå¢ããŠããããããšãŸãé¢åã§ãããå¿ãããããã®ã§ãããã£ãŠãŸãšãããããã®ãããã®ããªãšæããŸãã
Terragruntã䜿ããªãå Žåãã ãããã·ã§ã«ã¹ã¯ãªããåããããå®è¡ããããã®æé ãæžãããããŠããã§ããã