[英]Terraform environments - how to get it DRY
我們正在大量使用Terraform進行AWS Cloud配置。 我們的基礎terraform結構如下所示:
├─ modules
├── x
├── y
├─ environments
├── dev
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── uat
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf
當我們達到我們有許多模塊和許多環境的程度時,代碼重復現在變得更加嚴重,我們希望盡可能多地擺脫它。
我們目前主要關注的是output.tf
文件 - 每次擴展現有模塊或添加新模塊時,我們都需要為它設置特定於環境的配置(這是預期的),但我們仍然需要復制/粘貼輸出結果所需的部分輸出到output.tf
(如IP地址,AWS ARN等)。
有沒有辦法擺脫重復的output.tf
文件? 我們是否可以在模塊本身中定義所需的輸出,並在我們為特定環境運行terraform時查看所有已定義的輸出?
解決此問題的一種方法是創建base
環境,然后對公共元素進行符號鏈接,例如:
├─ modules
├── x
├── y
├─ environments
├── base
│ ├── output.tf
│ └── variables.tf
├── dev
│ ├── main.tf
│ ├── output.tf -> ../base/output.tf
│ └── variables.tf -> ../base/variables.tf
├── uat
│ ├── main.tf
│ ├── output.tf -> ../base/output.tf
│ └── variables.tf -> ../base/variables.tf
├── super_custom
│ ├── main.tf
│ ├── output.tf # not symlinked
│ └── variables.tf # not symlinked
└── prod
├── main.tf
├── output.tf -> ../base/output.tf
└── variables.tf -> ../base/variables.tf
這種方法只有在你的output.tf
和variables.tf
文件對於每個環境都相同的情況下才真正起作用,雖然你可以使用非super_custom
鏈接的變種(例如上面的super_custom
),但這可能會讓人感到困惑,因為並不是很明顯哪些環境是自定義的哪些不是。 因人而異。 我嘗試將環境之間的更改限制為每個環境的.tfvars
文件。
值得一讀Charity Major關於tfstate文件的優秀帖子 ,這讓我走上了這條道路。
我們構建並開源Terragrunt來解決這個問題。 Terragrunt的功能之一是能夠下載遠程Terraform配置。 我們的想法是,您只需在一個倉庫中為您的基礎架構定義一次Terraform代碼,例如, modules
:
└── modules
├── app
│ └── main.tf
├── mysql
│ └── main.tf
└── vpc
└── main.tf
此repo包含典型的Terraform代碼,但有一點不同:代碼中應該在環境之間存在差異的任何內容都應作為輸入變量公開。 例如,app模塊可能會公開以下變量:
variable "instance_count" {
description = "How many servers to run"
}
variable "instance_type" {
description = "What kind of servers to run (e.g. t2.large)"
}
在一個單獨的倉庫中,例如,live,您可以為所有環境定義代碼,現在每個組件只包含一個.tfvars
文件(例如app/terraform.tfvars
, mysql/terraform.tfvars
等)。 這為您提供了以下文件布局:
└── live
├── prod
│ ├── app
│ │ └── terraform.tfvars
│ ├── mysql
│ │ └── terraform.tfvars
│ └── vpc
│ └── terraform.tfvars
├── qa
│ ├── app
│ │ └── terraform.tfvars
│ ├── mysql
│ │ └── terraform.tfvars
│ └── vpc
│ └── terraform.tfvars
└── stage
├── app
│ └── terraform.tfvars
├── mysql
│ └── terraform.tfvars
└── vpc
└── terraform.tfvars
請注意,任何文件夾中都沒有Terraform配置( .tf
文件)。 相反,每個.tfvars
文件指定一個terraform { ... }
塊,指定從何處下載Terraform代碼,以及該Terraform代碼中輸入變量的特定於環境的值。 例如, stage/app/terraform.tfvars
可能如下所示:
terragrunt = {
terraform {
source = "git::git@github.com:foo/modules.git//app?ref=v0.0.3"
}
}
instance_count = 3
instance_type = "t2.micro"
而prod/app/terraform.tfvars
可能如下所示:
terragrunt = {
terraform {
source = "git::git@github.com:foo/modules.git//app?ref=v0.0.1"
}
}
instance_count = 10
instance_type = "m2.large"
有關詳細信息,請參閱Terragrunt文檔 。
如果您的dev
, uat
和prod
環境具有相同的形狀,但具有不同的屬性,您可以利用工作空間來分隔您的環境狀態,以及單獨的*.tfvars
文件來指定不同的配置。
這可能看起來像:
├─ modules
│ ├── x
│ └── y
├── dev.tfvars
├── prod.tfvars
├── uat.tfvars
├── main.tf
├── outputs.tf
└── variables.tf
您可以使用以下命令創建新工作區:
terraform workspace new uat
然后部署更改變為:
terraform workspace select uat
terraform apply --var-file=uat.tfvars
工作區功能可確保分別管理不同的環境狀態,這是一個獎勵。
這種方法僅適用於環境之間的差異足夠小以至於在單個模塊中封裝邏輯high_availability
(例如,具有high_availability
標記,為uat
和prod
添加一些額外的冗余基礎uat
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.