我个人对terraform module的理解是,这个东西更像是我们传统意义上的函数,我们在一个地方定义了一个函数以后,以后相同的功能直接调用函数就可以了,不需要重新copy paste代码,当然我们也可以传递参数,这样函数执行的过程中还有差异化的选择, Terraform module的定义完全相同
我们使用https://github.com/gruntwork-io/intro-to-terraform中代码来做详细的讲解
首先,目录结构,我们要创建一个目录叫modules
1 2 3 4 5 6 7 8 9 |
$tree modules modules └── services └── webserver-cluster ├── main.tf ├── outputs.tf └── variables.tf 2 directories, 3 files |
目录结构如上,其中,webserver-cluster中的内容就是创建一个包含hello word的简单应用,创建一个ec2 (通过Auto Scaling Group实现)并且创建了elb在前端做负载
这个时候,我们就可以使用我们这个module了,创建test1.tf
1 2 3 4 5 6 7 |
$tree stage stage └── services └── webserver-cluster └── main.tf 2 directories, 1 file |
注意stage 目录和 modules目录同级别
1 2 3 4 5 6 7 |
$cat stage/services/webserver-cluster/main.tf provider "aws" { region = "us-east-2" } module "webserver_cluster" { source = "../../../modules/services/webserver-cluster" } |
这样我就可以调用module webserver_cluster来创建我们的cluster了
我们也可以穿入具体参数,如果我们想要传递参数,那么我们必须在module中做了相应的定义,我们看一下如何定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
cat modules/services/webserver-cluster/variables.tf # --------------------------------------------------------------------------------------------------------------------- # ENVIRONMENT VARIABLES # Define these secrets as environment variables # --------------------------------------------------------------------------------------------------------------------- # AWS_ACCESS_KEY_ID # AWS_SECRET_ACCESS_KEY # --------------------------------------------------------------------------------------------------------------------- # REQUIRED PARAMETERS # --------------------------------------------------------------------------------------------------------------------- variable "cluster_name" { description = "The name to use for all the cluster resources" type = string } variable "instance_type" { description = "The type of EC2 Instances to run (e.g. t2.micro)" type = string } variable "min_size" { description = "The minimum number of EC2 Instances in the ASG" type = number } variable "max_size" { description = "The maximum number of EC2 Instances in the ASG" type = number } # --------------------------------------------------------------------------------------------------------------------- # OPTIONAL PARAMETERS # --------------------------------------------------------------------------------------------------------------------- variable "server_port" { description = "The port the server will use for HTTP requests" type = number default = 8080 } variable "elb_port" { description = "The port the ELB will use for HTTP requests" type = number default = 80 } |
也就是说,我们在调用module的时候,可以同时传入这些参数,当然也可以不传入,不传入的话module就是用默认值
类似这样
1 2 3 4 |
module "webserver_cluster" { source = "../../../modules/services/webserver-cluster" cluster_name = "webservers-stage" } |
但是使用module的时候有一个小小问题,如果我们想使用module中生成的instance或者asg来做一些操作,例如,自动扩容和自动缩减,这个时候我们就要在test1.tf中增加如下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
resource "aws_autoscaling_schedule" "scale_out_business_hours" { scheduled_action_name = "scale-out-during-business-hours" min_size = 2 max_size = 10 desired_capacity = 10 recurrence = "0 9 * * *" } resource "aws_autoscaling_schedule" "scale_in_at_night" { scheduled_action_name = "scale-in-at-night" min_size = 2 max_size = 10 desired_capacity = 2 recurrence = "0 17 * * *" } |
如上内容有一个问题是,他们缺少必要输入autoscaling_group_name,只有知道了我们要对哪个ASG进行操作我们才可以进行真正的扩容,但是,这部分是在module中的,我们需要从module中获取具体数值,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
resource "aws_autoscaling_schedule" "scale_out_business_hours" { scheduled_action_name = "scale-out-during-business-hours" min_size = 2 max_size = 10 desired_capacity = 10 recurrence = "0 9 * * *" autoscaling_group_name = module.webserver_cluster.asg_name } resource "aws_autoscaling_schedule" "scale_in_at_night" { scheduled_action_name = "scale-in-at-night" min_size = 2 max_size = 10 desired_capacity = 2 recurrence = "0 17 * * *" autoscaling_group_name = module.webserver_cluster.asg_name } |
关键点在于asg_name,如果我们想使用这个,必须让module在执行完成后把这个参数赋值,具体操作如下:
1 2 3 4 5 |
$cat modules/services/webserver-cluster/outputs.tf output "asg_name" { value = aws_autoscaling_group.example.name description = "The name of the Auto Scaling Group" } |
我们在module的outputs.tf中定义了这么一个asg_name,也就是谁调用了module,那么这个module执行完就会返回一个asg_name,然后完成的名字就是module.webserver_cluster.asg_name
另外module有一个问题就是如果module发生修改,那么所有调用它的环境在下一次apply的时候都会发生改变,我们可以通过git来解决这个问题,因为module的调用支持github
例如:
1 2 3 4 5 6 7 |
module "webserver_cluster" { source = "github.com/foo/modules//webserver-cluster?ref=v0.0.1" cluster_name = "webservers-stage" instance_type = "t2.micro" min_size = 2 max_size = 2 } |
Latest posts by Zhiming Zhang (see all)
- aws eks node 自动化扩展工具 Karpenter - 8月 10, 2022
- ReplicationController and ReplicaSet in Kubernetes - 12月 20, 2021
- public key fingerprint - 5月 27, 2021