我们需要将公司防火墙中的一些弹性IP列入白名单,作为SSH的允许目标IP。有没有办法使用Terraform配置堡垒实例并为其分配特定的弹性IP?并且,同样地,当堡垒被摧毁时,它是否将EIP返回到配置池?显然,我们不希望从我们的AWS账户中取消分配EIP。
答案 0 :(得分:3)
目前,当您可以选择将弹性IP附加到实例或弹性网络接口时,Terraform仅支持在EIP creation上将弹性IP附加到EC2实例。 NAT Gateways目前允许您在创建NAT网关时将EIP与其关联,但这是一个稍微特殊的情况。
instance module本身只允许布尔选择实例是否获得正常的公共IP地址。有一个GitHub issue允许实例与预先存在的EIP相关联,但在编写时没有拉动请求来支持它。
如果只是想要在公司防火墙上打开一个端口,而不必为了定期拆除的堡垒框而触摸它,你就可以开放允许Terraform创建和管理EIP了然后,您可以执行以下操作:
resource "aws_instance" "bastion" {
ami = "ami-abcdef12"
instance_type = "t2.micro"
tags {
Name = "bastion"
}
}
output "bastion_id" {
value = "${aws_instance.bastion.id}"
}
在一个单独的文件夹中,您可以完成EIP定义,并从remote state file查找堡垒主机的输出实例ID,并在应用EIP时使用它:
resource "terraform_remote_state" "remote_state" {
backend = "s3"
config {
bucket = "mybucketname"
key = "name_of_key_file"
}
}
resource "aws_eip" "bastion_eip" {
vpc = true
instance = "${terraform_remote_state.remote_state.output.bastion_id}"
lifecycle {
prevent_destroy = true
}
}
在上面的示例中,我使用了@BMW的approach,因此您应该在尝试销毁EIP的任何计划中收到错误,就像故障安全一样。
这至少应该允许你使用Terraform构建和销毁短期实例,但每次都将相同的EIP应用于实例,这样你就不必更改防火墙上的任何内容了。
使用Terraform的一种稍微简单的方法是将EIP定义放在与堡垒实例相同的.tf
文件/文件夹中,但是您将无法使用Terraform销毁该文件夹中的任何内容(包括堡垒)实例本身)如果您保留lifecycle
配置块,因为它只是在计划期间导致错误。每次销毁实例时,删除块只会让你回到销毁EIP。
答案 1 :(得分:3)
现有答案已过时。由于此更改,现在可以关联现有的弹性IP:https://github.com/hashicorp/terraform/pull/5236
文档:https://www.terraform.io/docs/providers/aws/r/eip_association.html
摘录:
aws_eip_association
将AWS EIP Association提供为顶级 资源,将弹性IP与AWS实例关联和取消关联 和网络接口。
注意:aws_eip_association在EIP的情况下非常有用 预先存在或分发给客户或用户,因此不能 改变了。
答案 2 :(得分:1)
我花了一些时间解决这个问题,发现其他答案很有帮助,但不完整。
对于那些尝试使用Terraform重新分配AWS弹性IP的人,我们可以使用terraform_remote_state
和aws_eip_association
的组合来这样做。让我解释一下。
我们应该在父文件夹中使用两个单独的根模块:
parent_folder
├--elasticip
| └main.tf
└--server
└main.tf
在elasticip/main.tf
中,您可以使用以下代码来创建弹性IP,并将状态存储在本地后端中,以便您可以从服务器模块访问其输出。输出变量名称不能为“ id”,因为这将与远程状态变量id冲突,并且将不起作用。只需使用其他名称,例如eip_id
。
terraform {
backend "local" {
path = "../terraform-eip.tfstate"
}
}
resource "aws_eip" "main" {
vpc = true
lifecycle {
prevent_destroy = true
}
}
output "eip_id" {
value = "${aws_eip.main.id}"
}
然后在server/main.tf
中,以下代码将创建服务器并将弹性IP与之关联。
data "terraform_remote_state" "eip" {
backend = "local"
config {
path = "../terraform-eip.tfstate"
}
}
resource "aws_eip_association" "eip_assoc" {
instance_id = "${aws_instance.web.id}"
allocation_id = "${data.terraform_remote_state.eip.eip_id}"
}
resource "aws_instance" "web" {
ami = "insert-your-AMI-ref"
}
完成所有设置后,您可以进入elasticip
文件夹,运行terraform init
和terraform apply
以获得弹性IP。然后进入server
文件夹,并运行相同的两个命令以获取具有其关联的弹性IP的服务器。在服务器文件夹中,您可以运行terraform destroy
和terraform apply
,新服务器将获得相同的弹性IP。
答案 3 :(得分:0)
是的,你可以阻止它。将我们不希望从我们的AWS账户中取消分配EIP。
prevent_destroy
设为true
resource "aws_eip" "bastion_eip" {
count = "${var.num_bastion}"
lifecycle {
prevent_destroy = true
}
}
关于EIP分配,请参阅@ ydaetskcoR的回复
答案 4 :(得分:0)
如果您使用的是自动缩放组,则可以在用户数据中进行。 https://forums.aws.amazon.com/thread.jspa?threadID=52601
#!/bin/bash
# configure AWS
aws configure set aws_access_key_id {MY_ACCESS_KEY}
aws configure set aws_secret_access_key {MY_SECRET_KEY}
aws configure set region {MY_REGION}
# associate Elastic IP
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
ALLOCATION_ID={MY_EIP_ALLOC_ID}
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOCATION_ID --allow-reassociation