【发布时间】:2022-02-10 01:03:36
【问题描述】:
我正在尝试使用 ubuntu 映像启动 EC2 实例。我想通过 terraform 提供对实例的 ssh 访问,安装和运行 apache 服务器,并打开端口 80。
我的 EC2 有以下 remote-exec 代码
provisioner "remote-exec" {
inline = [
"sudo apt update -y",
"sudo apt upgrade -y",
"sudo apt install apache2 -y",
"sudo systemctl status apache2"
]
}
但是,在所有命令都成功执行后,即 systemctl 显示正确的响应,我的提示挂在 aws_instance.web_server_instance: Still creating...
我的完整代码
terraform {
required_version = "~> 1.1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.74.1"
}
local = {
source = "hashicorp/local"
version = "2.1.0"
}
tls = {
source = "hashicorp/tls"
version = "3.1.0"
}
}
}
provider "aws" {
profile = "terraform"
region = "us-east-1"
}
locals {
application_name = "web_server"
}
# ssh key
resource "tls_private_key" "web_server_key_pair_gen" {
algorithm = "RSA"
}
resource "local_file" "web_server_private_key" {
content = tls_private_key.web_server_key_pair_gen.private_key_pem
filename = "${local.application_name}_private_key.pem"
}
resource "aws_key_pair" "web_server_public_key" {
key_name = "${local.application_name}_public_key"
public_key = tls_private_key.web_server_key_pair_gen.public_key_openssh
}
# security group
resource "aws_security_group" "web_server_security_group" {
name = "${local.application_name}_security_group"
dynamic "ingress" {
for_each = [
{ port = 22, description = "ssh" },
{ port = 80, description = "http" },
]
content {
description = ingress.value.description
from_port = ingress.value.port
to_port = ingress.value.port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = []
prefix_list_ids = []
security_groups = []
self = false
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${local.application_name}_security_group"
}
}
# ami lookup
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"]
}
# ec2 instance
resource "aws_instance" "web_server_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.web_server_security_group.id]
key_name = aws_key_pair.web_server_public_key.key_name
associate_public_ip_address = true
connection {
user = "ubuntu"
private_key = tls_private_key.web_server_key_pair_gen.private_key_pem
host = self.public_ip
}
provisioner "local-exec" {
command = "chmod 600 ${local_file.web_server_private_key.filename}"
}
provisioner "remote-exec" {
inline = [
"sudo apt update -y",
"sudo apt upgrade -y",
"sudo apt install apache2 -y",
"sudo systemctl status apache2"
]
}
tags = {
Name = "${local.application_name}_instance"
}
}
output "server_public_ip" {
value = aws_instance.web_server_instance.public_ip
}
【问题讨论】:
-
你为什么使用 remote-exec 而不是用户数据 cloud-init 脚本?
-
嘿@MarkB,感谢您的回复。我今天早上开始学习 terraform,只是出于教育目的进行尝试。
-
远程供应商通常被认为是 Terraform 中的“最后手段”。 AWS EC2 提供了一种通过用户数据脚本初始化服务器的方法,这将更加可靠。
-
官方文档部分Provisioners are a Last Resort 中提供了有关供应商使用权衡的更多信息以及其他一些需要考虑的选项。具体而言,请参阅将数据传递到虚拟机和其他计算资源以了解此用例。
标签: amazon-web-services terraform terraform-provider-aws