使用Terraform启动具有不同配置的多个EC2资源(VPC不由TF维护)

99次阅读
没有评论

问题描述

计划使用Terraform来创建托管Oracle数据库的EC2实例。虽然他们已经能够实现这一点,但是他们有一些问题,希望能够得到建议和反馈。
以下是他们计划的目录结构:

|aws
|---Environments
|------STAGING
|---------Modules
|------------Compute
|------------Networking
|------PRODUCTION
|---------Modules
|------------Compute
|------------Networking

问题:
1. 他们能够使用现有的VPC创建EC2实例。由于VPC不是由他们的团队拥有,他们想知道在EC2资源中将VPC ID、子网ID等作为变量是否足够,还是最佳实践是将它们保留在现有VPC的模块中?总体上,他们的tf代码不会管理VPC,只是使用给定的VPC,但希望使其动态化,以便更改简单且DRY。
2. 他们计划进行持续开发,即开发人员/请求者将能够请求具有特定数据库版本的新EC2实例。目前,他们正在使用引导脚本安装数据库。尽管这符合预期,但如果配置稍有变化,增加超过1个实例的计数是可以的,但是如果配置稍有变化,如何处理?
例如:如果我需要为新实例增加根卷的容量,更改现有资源会显示一个计划,将销毁现有资源并重新创建。如何实现这一点?当配置更改为新的EC2实例时,是否只能复制aws_instance资源?
如果新实例以t2.large(实例类型作为变量传递)启动,而旧实例运行在t2.micro上,如果我只增加计数,它是否也会重新创建旧实例?
此外,是否有一种自动化这个过程的方法,例如将新EC2实例的模板附加到现有的.tf文件中?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

对于第一个问题,您可以使用远程后端作为数据源。这在我们这里运行良好,但是这个项目还不是很成熟,我们可能会重构十次。

data "terraform_remote_state" "network" {
  backend = "s3"
  config {
    // 一些与配置相关的变量可能会放在这里
  }
}

然后,对于不管理网络的团队来说,他们可以创建一个实例,如下所示(特别注意subnet_id):

resource "aws_instance" "oracle_ec2" {
  ami           = "${lookup(var.ami, var.region)}"
  instance_type = "${var.instance_type}"
  key_name      = "${var.key_name}"
  subnet_id     = "${data.terraform_remote_state.network.subnet_id}"
}

网络团队应该能够管理网络基础设施,并且您应该能够根据当前状态使用这些值。
Terraform远程状态数据源

对于第二个问题,如果将实例类型从t2.micro更改为t2.large,那么是的,t2.micro实例将被销毁并替换为t2.large。关键是要保持不变性,除了像更改标签这样的元数据更改之外。可以查看生命周期钩子以减轻一些痛苦。

lifecycle {
  create_before_destroy = true
}

如果只增加计数,则不会重新创建当前实例。Terraform将检查状态以查看您当前有多少实例。如果需要更多实例,Terraform将知道要创建多少个实例并创建所需的实例。

对于第三个问题,我不确定您具体指的是什么。我可以说的是,将数据耦合到实例本身会使实例的不可变性和使用Terraform变得更加困难。我脑海中的一个(未经测试和证明的)想法和潜在解决方案是:

// 创建一个EBS卷
resource "aws_ebs_volume" "oracle-data" {
  ...
}

// 将该卷附加到实例
resource "aws_volume_attachment" "oracle-data-attachment" {
  ...
}

使用一些bash脚本来创建和挂载新卷,以与aws_volume_attachment资源一起使用。这可能会创建一个保留EBS卷的新实例,然后将其重新附加到新实例上。

正文完