paint-brush
解锁 IaC 第 3 部分:您的首次 Terraform 部署!经过@chrisray
556 讀數
556 讀數

解锁 IaC 第 3 部分:您的首次 Terraform 部署!

经过 Chris Ray55m2023/09/30
Read on Terminal Reader

太長; 讀書

使用 Terraform 进行构建设置非常困难!在第 3 部分中,我们开始讨论正题,并使用 Terraform 在 AWS 中构建 Splunk 服务器。
featured image - 解锁 IaC 第 3 部分:您的首次 Terraform 部署!
Chris Ray HackerNoon profile picture
0-item


让我们玩得开心吧!

让我们面对现实吧:关于 IaC 等技术问题的 3 部分系列可能是一个挑战。我相信到目前为止,你已经多次被拉离这个话题了。进入第三部分是令人兴奋的 - 这是有趣的部分开始的时候。这是橡胶上路的时刻。如果您感觉自己快要坚持不住了,并且怀疑自己能否完成这一部分,那么很高兴知道大多数人也有这样的感觉。很少有人会深入研究像这样抽象的东西,并在第一次(或第三次)尝试中就成功。我们开始谈正事吧!

对于第一次部署,我们使用大家都知道的名称 Splunk。在此脚本中,我们将部署一台已安装并配置 Splunk 的服务器。这将使用Amazon 系统映像(AMI)。有许多 AMI 可供选择。有些是不同的操作系统,例如 Windows 或 Linux;有些是 Linux 的不同发行版,例如 Ubuntu、CentOS 等,有些是像这个这样的预构建应用程序。


我们将启动 Splunk EC2服务器(“Splunk 实例”),创建网络访问权限,仅允许您的公共 IP 地址通过 TCP 端口 8000(默认 Splunk UI 端口)访问它,然后使用简单的 Terraform 销毁所有这些当我们完成后发出命令。


我会将单个terraform文件 (main.tf) 分成几个小块,以便我们可以更轻松地浏览每个部分。然后,最后,我会将它们放在一起,以便我们可以执行它。

如何在 Terraform 土地上自己解决问题

在我们开始之前,重要的是您知道可以在哪里找到我在这里没有考虑到的问题的答案。举个例子,当我开始在 Terraform 中构建时,我想知道,“我如何知道哪些参数(这是定义资源的方式,例如 EC2 实例中的虚拟机类型或安全组中允许的入口协议)在此示例中,以及此处未回答的许多其他问题,您可以转到Terraform 注册表以了解有关可用提供程序、资源、参数和语法的更多信息。


例如,在注册表中,我可以找到“安全组”资源(我们将在本教程中使用),然后转到“输入”选项卡查看所有可用参数(他们称之为变量,仅供参考)当我们配置资源时允许。好的...绕道完成,进入您的第一个 TF 部署的配置!

使用 Terraform 进行构建

第一步,我们需要定义我们要使用的提供者。我们在 AWS 中工作,因此提供商将是“AWS”。我们还将在这里定义我们想要研究的区域。


 provider "aws" { region = "us-west-1" }


如果您还记得的话,我说过我们将为虚拟机 (EC2) 使用 Amazing Machine Image (AMI)。在这里,我们使用 Terraform“data”关键字来搜索资源“aws_ami”。此外,我们为搜索过程中返回的所有数据命名为“Splunk”。这样我们就可以在代码中的其他位置引用这些数据(稍后请记住这一点)...


由于搜索任何内容都需要某种方式来将搜索结果限制为我们想要查找的内容,因此我们使用过滤器关键字,然后向其传递两个参数:“名称”和“值”。在这里,我们指示“aws_ami”的搜索在“名称”字段中搜索以“Splunk”开头的任何内容。虽然这可能需要调整得更具体,但在本例中,此过滤器很好。


 data "aws_ami" "splunk" { most_recent = true filter { name = "name" values = ["splunk*"] } }


在 AWS 中,对资源的网络访问通常通过称为“安全组”的资源进行控制。在我们的示例中,我们将使用一个安全组,该安全组允许从我的 IP 地址(或您的 IP 地址,当您创建此脚本时)进行 TCP 端口 8000 入站(“入口”)。因为我们在包含非敏感信息的私人帐户中使用 Splunk,我将允许它进行出站通信(“出口”)。但是,如果这是生产环境,您将需要确定必要的 IP 和端口范围,并限制访问它们以遵循最佳实践。


请注意,我定义了入口参数,包括协议和“cidr_blocks”。这很重要,因为此处的错误配置可能会意外地向更广泛的互联网开放环境。如果您有兴趣了解如何为您的 AWS 环境提供额外的网络安全性,请告诉我 - 我可以创建一个有关添加应用程序负载均衡器的教程( ALB)为此配置提供额外的安全功能。


 resource "aws_security_group" "splunksg" { name = "SplunkSecGroup" description = "Allow-on-port-8000" ingress { from_port = 8000 to_port = 8000 protocol = "tcp" cidr_blocks = ["YOUR_IP_HERE"] # Replace 'YOUR_PUBLIC_HERE' with your public IP address } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } }


最后,我们聚集于此的原因 - 将运行 Splunk 的虚拟机。与 Terraform 代码的所有其他部分一样,我们首先定义一个资源(在本例中为“aws_instance”)并将其命名为“splunk_ec2”,然后继续使用参数定义其下面的其他参数。


还记得我们上面使用的“data”关键字在“aws_ami”中搜索最新的“Splunk*”AMI 吗?我们的名字是“Splunk”。在这里,在 EC2 实例配置中,我们可以引用该查询中包含的数据。我们通过使用“ami”参数来引用它,并说它等于“data.aws_ami.splunk.id”中的任何内容。这是一个需要理解的非常重要的概念,所以让我们花两分钟来分解它:


  1. data.aws_ami. ”引用我们上面创建的代码块中的 data 关键字。
  2. splunk.id ”引用我们为该数据指定的名称“Splunk”,而最后一段“id”引用“data”查询返回的 AMI ID。 AMI ID 是一个人类不易记住的字符串,但对于机器来说是唯一且易于使用的。


向下移动,我们说此 EC2 的 security_group 是我们上面定义的“splunksg”安全组。这使用与 AMI“数据”命名相同的逻辑。 IE 中,它以资源名称、我们定义的对象名称开头,然后是变量“.name”,我们也将其定义为“ SplunkSecGroup ”,另请注意,您可以为此使用 t2.micro 的instance_type,并且它有效 - 只是速度很慢,所以我选择 t2.medium。


最后,我们向该实例应用标签,这在 AWS 账户增长且跟踪资产变得更加困难时非常有用。


 resource "aws_instance" "splunk_ec2" { ami = data.aws_ami.splunk.id instance_type = "t2.medium" security_groups = [aws_security_group.splunksg.name] tags = { Name = "SplunkInstance" } }


现在,我知道您可以直接跳到这一部分并将其放入文件系统中并运行它,并在您“完成”教程后感到与世界和平,但不要这样做。别那么懒。花时间和我一起阅读和构建的价值在于犯错误的痛苦和纠正这些错误的快乐。


把它们放在一起,我们应该有一个如下所示的 terraform 脚本:


 provider "aws" { region = "us-west-1" } data "aws_ami" "splunk" { most_recent = true filter { name = "name" values = ["splunk*"] } } resource "aws_security_group" "splunksg" { name = "SplunkSecGroup" description = "Allow-on-port-8000" ingress { from_port = 8000 to_port = 8000 protocol = "tcp" cidr_blocks = ["YOUR_PUBLIC_HERE/32"] # Replace 'YOUR_PUBLIC_HERE' with your public IP address } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_instance" "splunk_ec2" { ami = data.aws_ami.splunk.id instance_type = "t2.medium" security_groups = [aws_security_group.splunksg.name] tags = { Name = "SplunkInstance" } }


哇,看看,43 行代码!听起来好像很多,但您已经完成了 - 您可以更新它、用它创建、销毁它或共享它!


因为我们已经在 解锁 IaC的第 2 部分中设置了所有必需的部分,所以所需要做的就是使用正确的扩展名保存文件(让我们使用main.tf)。


以管理员身份打开 CMD 或 PowerShell(CTRL+SHIFT+CLICK 或右键单击并“运行为...”),“CD”或将目录更改为与我们刚刚创建的文件 (main.tf) 相同的位置,然后发出以下命令命令:

地形初始化


c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>terraform init Initializing the backend... Initializing provider plugins... - Reusing previous version of hashicorp/aws from the dependency lock file - Using previously-installed hashicorp/aws v5.1.0 Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.


Terraform init在该目录中初始化 Terraform。这本质上是启动 Terraform。


地形计划


c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>terraform plan Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_instance.splunk_server will be created + resource "aws_instance" "splunk_server" { + ami = "ami-0b5cb59327b8d7e1f" + arn = (known after apply) + associate_public_ip_address = true + availability_zone = (known after apply) + cpu_core_count = (known after apply) + cpu_threads_per_core = (known after apply) + disable_api_stop = (known after apply) + disable_api_termination = (known after apply) + ebs_optimized = (known after apply) + get_password_data = false + host_id = (known after apply) + host_resource_group_arn = (known after apply) + iam_instance_profile = (known after apply) + id = (known after apply) + instance_initiated_shutdown_behavior = (known after apply) + instance_state = (known after apply) + instance_type = "t3.large" + ipv6_address_count = (known after apply) + ipv6_addresses = (known after apply) + key_name = (known after apply) + monitoring = (known after apply) + outpost_arn = (known after apply) + password_data = (known after apply) + placement_group = (known after apply) + placement_partition_number = (known after apply) + primary_network_interface_id = (known after apply) + private_dns = (known after apply) + private_ip = (known after apply) + public_dns = (known after apply) + public_ip = (known after apply) + secondary_private_ips = (known after apply) + security_groups = (known after apply) + source_dest_check = true + subnet_id = (known after apply) + tags_all = (known after apply) + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) + capacity_reservation_specification { + capacity_reservation_preference = (known after apply) + capacity_reservation_target { + capacity_reservation_id = (known after apply) + capacity_reservation_resource_group_arn = (known after apply) } } + cpu_options { + amd_sev_snp = (known after apply) + core_count = (known after apply) + threads_per_core = (known after apply) } + ebs_block_device { + delete_on_termination = (known after apply) + device_name = (known after apply) + encrypted = (known after apply) + iops = (known after apply) + kms_key_id = (known after apply) + snapshot_id = (known after apply) + tags = (known after apply) + throughput = (known after apply) + volume_id = (known after apply) + volume_size = (known after apply) + volume_type = (known after apply) } + enclave_options { + enabled = (known after apply) } + ephemeral_block_device { + device_name = (known after apply) + no_device = (known after apply) + virtual_name = (known after apply) } + maintenance_options { + auto_recovery = (known after apply) } + metadata_options { + http_endpoint = (known after apply) + http_put_response_hop_limit = (known after apply) + http_tokens = (known after apply) + instance_metadata_tags = (known after apply) } + network_interface { + delete_on_termination = (known after apply) + device_index = (known after apply) + network_card_index = (known after apply) + network_interface_id = (known after apply) } + private_dns_name_options { + enable_resource_name_dns_a_record = (known after apply) + enable_resource_name_dns_aaaa_record = (known after apply) + hostname_type = (known after apply) } + root_block_device { + delete_on_termination = (known after apply) + device_name = (known after apply) + encrypted = (known after apply) + iops = (known after apply) + kms_key_id = (known after apply) + tags = (known after apply) + throughput = (known after apply) + volume_id = (known after apply) + volume_size = (known after apply) + volume_type = (known after apply) } } # aws_security_group.splunk_server will be created + resource "aws_security_group" "splunk_server" { + arn = (known after apply) + description = "Managed by Terraform" + egress = (known after apply) + id = (known after apply) + ingress = [ + { + cidr_blocks = [ + "[redacted]/32", ] + description = "" + from_port = 22 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 22 }, + { + cidr_blocks = [ + "[redacted]/32", ] + description = "" + from_port = 8000 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 8000 }, ] + name = (known after apply) + name_prefix = "splunk-group" + owner_id = (known after apply) + revoke_rules_on_delete = false + tags_all = (known after apply) + vpc_id = (known after apply) } # aws_subnet.splunk_server will be created + resource "aws_subnet" "splunk_server" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = (known after apply) + availability_zone_id = (known after apply) + cidr_block = "172.31.1.0/28" + enable_dns64 = false + enable_resource_name_dns_a_record_on_launch = false + enable_resource_name_dns_aaaa_record_on_launch = false + id = (known after apply) + ipv6_cidr_block_association_id = (known after apply) + ipv6_native = false + map_public_ip_on_launch = false + owner_id = (known after apply) + private_dns_hostname_type_on_launch = (known after apply) + tags_all = (known after apply) + vpc_id = "vpc-[redacted]" } Plan: 3 to add, 0 to change, 0 to destroy. ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>


完成后,最好运行terraform plan ,这是一种查看Terraform 构建将做什么的方法,而无需实际对云环境进行任何更改。仔细检查此输出并确保您看到的内容与您的期望相符。

地形应用


c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>terraform apply Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_instance.splunk_server will be created + resource "aws_instance" "splunk_server" { + ami = "ami-0b5cb59327b8d7e1f" + arn = (known after apply) + associate_public_ip_address = true + availability_zone = (known after apply) + cpu_core_count = (known after apply) + cpu_threads_per_core = (known after apply) + disable_api_stop = (known after apply) + disable_api_termination = (known after apply) + ebs_optimized = (known after apply) + get_password_data = false + host_id = (known after apply) + host_resource_group_arn = (known after apply) + iam_instance_profile = (known after apply) + id = (known after apply) + instance_initiated_shutdown_behavior = (known after apply) + instance_state = (known after apply) + instance_type = "t3.large" + ipv6_address_count = (known after apply) + ipv6_addresses = (known after apply) + key_name = (known after apply) + monitoring = (known after apply) + outpost_arn = (known after apply) + password_data = (known after apply) + placement_group = (known after apply) + placement_partition_number = (known after apply) + primary_network_interface_id = (known after apply) + private_dns = (known after apply) + private_ip = (known after apply) + public_dns = (known after apply) + public_ip = (known after apply) + secondary_private_ips = (known after apply) + security_groups = (known after apply) + source_dest_check = true + subnet_id = (known after apply) + tags_all = (known after apply) + tenancy = (known after apply) + user_data = (known after apply) + user_data_base64 = (known after apply) + user_data_replace_on_change = false + vpc_security_group_ids = (known after apply) + capacity_reservation_specification { + capacity_reservation_preference = (known after apply) + capacity_reservation_target { + capacity_reservation_id = (known after apply) + capacity_reservation_resource_group_arn = (known after apply) } } + cpu_options { + amd_sev_snp = (known after apply) + core_count = (known after apply) + threads_per_core = (known after apply) } + ebs_block_device { + delete_on_termination = (known after apply) + device_name = (known after apply) + encrypted = (known after apply) + iops = (known after apply) + kms_key_id = (known after apply) + snapshot_id = (known after apply) + tags = (known after apply) + throughput = (known after apply) + volume_id = (known after apply) + volume_size = (known after apply) + volume_type = (known after apply) } + enclave_options { + enabled = (known after apply) } + ephemeral_block_device { + device_name = (known after apply) + no_device = (known after apply) + virtual_name = (known after apply) } + maintenance_options { + auto_recovery = (known after apply) } + metadata_options { + http_endpoint = (known after apply) + http_put_response_hop_limit = (known after apply) + http_tokens = (known after apply) + instance_metadata_tags = (known after apply) } + network_interface { + delete_on_termination = (known after apply) + device_index = (known after apply) + network_card_index = (known after apply) + network_interface_id = (known after apply) } + private_dns_name_options { + enable_resource_name_dns_a_record = (known after apply) + enable_resource_name_dns_aaaa_record = (known after apply) + hostname_type = (known after apply) } + root_block_device { + delete_on_termination = (known after apply) + device_name = (known after apply) + encrypted = (known after apply) + iops = (known after apply) + kms_key_id = (known after apply) + tags = (known after apply) + throughput = (known after apply) + volume_id = (known after apply) + volume_size = (known after apply) + volume_type = (known after apply) } } # aws_security_group.splunk_server will be created + resource "aws_security_group" "splunk_server" { + arn = (known after apply) + description = "Managed by Terraform" + egress = (known after apply) + id = (known after apply) + ingress = [ + { + cidr_blocks = [ + "[redacted]/32", ] + description = "" + from_port = 22 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 22 }, + { + cidr_blocks = [ + "[redacted]/32", ] + description = "" + from_port = 8000 + ipv6_cidr_blocks = [] + prefix_list_ids = [] + protocol = "tcp" + security_groups = [] + self = false + to_port = 8000 }, ] + name = (known after apply) + name_prefix = "splunk-group" + owner_id = (known after apply) + revoke_rules_on_delete = false + tags_all = (known after apply) + vpc_id = (known after apply) } # aws_subnet.splunk_server will be created + resource "aws_subnet" "splunk_server" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = (known after apply) + availability_zone_id = (known after apply) + cidr_block = "172.31.1.0/28" + enable_dns64 = false + enable_resource_name_dns_a_record_on_launch = false + enable_resource_name_dns_aaaa_record_on_launch = false + id = (known after apply) + ipv6_cidr_block_association_id = (known after apply) + ipv6_native = false + map_public_ip_on_launch = false + owner_id = (known after apply) + private_dns_hostname_type_on_launch = (known after apply) + tags_all = (known after apply) + vpc_id = "vpc-[redacted]" } Plan: 3 to add, 0 to change, 0 to destroy. Changes to Outputs: + splunk_server_public_ip = (known after apply) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_subnet.splunk_server: Creating... aws_security_group.splunk_server: Creating... aws_subnet.splunk_server: Creation complete after 1s [id=subnet-053c39ae3dcc97112] aws_security_group.splunk_server: Creation complete after 2s [id=sg-03bf97ed2524e4aee] aws_instance.splunk_server: Creating... aws_instance.splunk_server: Still creating... [10s elapsed] aws_instance.splunk_server: Creation complete after 13s [id=i-050c4bad2d2a6ba93] Apply complete! Resources: 3 added, 0 changed, 0 destroyed. c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>


最后,运行terraform apply获取代码并将其应用到您的 AWS 账户。这可能需要几秒钟到一分钟的时间,但完成后您应该会收到一条成功消息。如果出现任何错误,请仔细检查该错误。地形错误通常是高质量的,并且会提供不需要太多(如果有的话)研究即可理解的线索。

Splunk登录

此时,您的 Splunk 服务器可能已准备好登录(需要一两分钟才能在 Splunk 上使用 UI)。要登录 Splunk,您需要三项信息:

  1. 用户名,即admin
  2. 密码,将为SPLUNK-<instanceid>
  3. AWS 中此 EC2 实例的 IP 地址和端口(例如http://10.10.10.10:8000


虽然可以从 Terraform 中提取 IP 地址并将其作为脚本的输出发送给您,或者使用AWS CLI收集此信息,但为了简单起见,我们在这里没有这样做。为了获取您的 IP 地址和实例 ID,您需要登录 AWS 控制台。


在服务菜单中搜索 EC2,然后单击 EC2,然后单击实例(正在运行)。在此视图中,您将看到正在运行的 EC2 实例的列表,除非您有其他有趣的事情正在进行,否则这应该只是一个。

单击正确的实例(或唯一的实例),在此视图中,您将在左上角看到“实例 ID”,可以通过单击左侧的复制按钮进行复制,在右侧,您将看到您的实例 ID。 IP地址。


获取该 IP 地址,并使用您选择的浏览器输入http://[instanceIP]:8000 ,然后按 Enter 键。您应该看到 Splunk 登录 - 如果没有看到,请再等待一两分钟 - Splunk 第一次启动需要(字面上的)2-3 分钟。请记住username = adminpassword = SPLUNK-[instanceID]


地形破坏

构建很棒,学习新东西很有趣 - 当你玩完后忘记关闭云资源很糟糕。 Terraform destroy 执行与 Terraform apply 相反的操作。它会破坏 terraform 文件中指定的基础设施。要使用 terraform destroy (您现在应该这样做),请返回命令行并输入terraform destroy 。 terraform destroy 的成功运行将通过缺少 Splunk UI(它可能会通知您已断开连接)以及 destroy 命令的输出来标记。


 c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>terraform destroy aws_subnet.splunk_server: Refreshing state... [id=subnet-053c39ae3dcc97112] aws_security_group.splunk_server: Refreshing state... [id=sg-03bf97ed2524e4aee] aws_instance.splunk_server: Refreshing state... [id=i-050c4bad2d2a6ba93] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_instance.splunk_server will be destroyed - resource "aws_instance" "splunk_server" { - ami = "ami-0b5cb59327b8d7e1f" -> null - arn = "arn:aws:ec2:us-west-2:625982356191:instance/i-050c4bad2d2a6ba93" -> null - associate_public_ip_address = true -> null - availability_zone = "us-west-2b" -> null - cpu_core_count = 1 -> null - cpu_threads_per_core = 2 -> null - disable_api_stop = false -> null - disable_api_termination = false -> null - ebs_optimized = false -> null - get_password_data = false -> null - hibernation = false -> null - id = "i-050c4bad2d2a6ba93" -> null - instance_initiated_shutdown_behavior = "stop" -> null - instance_state = "running" -> null - instance_type = "t3.large" -> null - ipv6_address_count = 0 -> null - ipv6_addresses = [] -> null - monitoring = false -> null - placement_partition_number = 0 -> null - primary_network_interface_id = "eni-059f68aecb53fc4bb" -> null - private_dns = "ip-172-31-1-11.us-west-2.compute.internal" -> null - private_ip = "172.31.1.11" -> null - public_dns = "[redacted].us-west-2.compute.amazonaws.com" -> null - public_ip = "[redacted]" -> null - secondary_private_ips = [] -> null - security_groups = [ - "splunk-group20230929124520702900000001", ] -> null - source_dest_check = true -> null - subnet_id = "subnet-053c39ae3dcc97112" -> null - tags = {} -> null - tags_all = {} -> null - tenancy = "default" -> null - user_data_replace_on_change = false -> null - vpc_security_group_ids = [ - "sg-03bf97ed2524e4aee", ] -> null - capacity_reservation_specification { - capacity_reservation_preference = "open" -> null } - cpu_options { - core_count = 1 -> null - threads_per_core = 2 -> null } - credit_specification { - cpu_credits = "unlimited" -> null } - enclave_options { - enabled = false -> null } - maintenance_options { - auto_recovery = "default" -> null } - metadata_options { - http_endpoint = "enabled" -> null - http_put_response_hop_limit = 1 -> null - http_tokens = "optional" -> null - instance_metadata_tags = "disabled" -> null } - private_dns_name_options { - enable_resource_name_dns_a_record = false -> null - enable_resource_name_dns_aaaa_record = false -> null - hostname_type = "ip-name" -> null } - root_block_device { - delete_on_termination = true -> null - device_name = "/dev/xvda" -> null - encrypted = false -> null - iops = 100 -> null - tags = {} -> null - throughput = 0 -> null - volume_id = "vol-0e283fb892f5fe38a" -> null - volume_size = 20 -> null - volume_type = "gp2" -> null } } # aws_security_group.splunk_server will be destroyed - resource "aws_security_group" "splunk_server" { - arn = "arn:aws:ec2:us-west-2:625982356191:security-group/sg-03bf97ed2524e4aee" -> null - description = "Managed by Terraform" -> null - egress = [] -> null - id = "sg-03bf97ed2524e4aee" -> null - ingress = [ - { - cidr_blocks = [ - "[redacted]/32", ] - description = "" - from_port = 22 - ipv6_cidr_blocks = [] - prefix_list_ids = [] - protocol = "tcp" - security_groups = [] - self = false - to_port = 22 }, - { - cidr_blocks = [ - "[redacted]/32", ] - description = "" - from_port = 8000 - ipv6_cidr_blocks = [] - prefix_list_ids = [] - protocol = "tcp" - security_groups = [] - self = false - to_port = 8000 }, ] -> null - name = "splunk-group20230929124520702900000001" -> null - name_prefix = "splunk-group" -> null - owner_id = "625982356191" -> null - revoke_rules_on_delete = false -> null - tags = {} -> null - tags_all = {} -> null - vpc_id = "vpc-002c2876364b2b282" -> null } # aws_subnet.splunk_server will be destroyed - resource "aws_subnet" "splunk_server" { - arn = "arn:aws:ec2:us-west-2:625982356191:subnet/subnet-053c39ae3dcc97112" -> null - assign_ipv6_address_on_creation = false -> null - availability_zone = "us-west-2b" -> null - availability_zone_id = "usw2-az1" -> null - cidr_block = "172.31.1.0/28" -> null - enable_dns64 = false -> null - enable_lni_at_device_index = 0 -> null - enable_resource_name_dns_a_record_on_launch = false -> null - enable_resource_name_dns_aaaa_record_on_launch = false -> null - id = "subnet-053c39ae3dcc97112" -> null - ipv6_native = false -> null - map_customer_owned_ip_on_launch = false -> null - map_public_ip_on_launch = false -> null - owner_id = "625982356191" -> null - private_dns_hostname_type_on_launch = "ip-name" -> null - tags = {} -> null - tags_all = {} -> null - vpc_id = "vpc-002c2876364b2b282" -> null } Plan: 0 to add, 0 to change, 3 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes aws_instance.splunk_server: Destroying... [id=i-050c4bad2d2a6ba93] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 10s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 20s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 30s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 40s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 51s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 1m1s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 1m11s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 1m21s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 1m31s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 1m41s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 1m51s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 2m1s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 2m11s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 2m21s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 2m31s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 2m41s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 2m51s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 3m1s elapsed] aws_instance.splunk_server: Still destroying... [id=i-050c4bad2d2a6ba93, 3m11s elapsed] aws_instance.splunk_server: Destruction complete after 3m14s aws_subnet.splunk_server: Destroying... [id=subnet-053c39ae3dcc97112] aws_security_group.splunk_server: Destroying... [id=sg-03bf97ed2524e4aee] aws_subnet.splunk_server: Destruction complete after 0s aws_security_group.splunk_server: Destruction complete after 0s Destroy complete! Resources: 3 destroyed. c:\Users\Chris\Documents\Projects\terraform\YT single server arch AWS>


完成这样的怪物教程并不容易。如果您已经做到了这一步,那么恭喜您!如果我错过了什么,很可能是这样,抱歉!此时,继续尝试这项新发现的技能是值得的 - 更改您的terraform 脚本并向 EC2 实例添加 EBS 卷以获取额外存储。添加 S3 以进行长期存储。了解如何自动将 SSH 密钥对添加到虚拟机,以便您可以通过 SSH 访问该虚拟机并使用 UI。最重要的是每天坚持玩这个,哪怕是一点点。


你停下来的那一刻就是你开始慢慢失去这项技能的那一刻。