用 IaC 的方式管理 EC2 实例 - 每天5分钟玩转 GPT 编程系列(1)

用 IaC 的方式管理 EC2 实例 - 每天5分钟玩转 GPT 编程系列(1)

·

4 min read

写在前面

咳咳,开个系列吧,就叫 《每天5分钟玩转 GPT 编程》。在这个系列里我们将分享各种借助 GPT 解决实际工作问题的经验,包括但不限于让 GPT 辅助写代码。

咳咳,敲黑板:本系列文章欢迎大家投稿,分享出你使用 GPT 的各种“奇淫技巧”,“sao 操作”,秀出你是如何借力 GPT 提升工作效率,解决实际工作问题的!

咳咳,我知道你想问:投稿有奖励吗?有,必须有,不过我还来不及备礼。我决定等收到第一篇投稿时再思考这个问题。

如果这是你第一次听说“DevChat”,那么我推荐你先阅读这篇文章《DevChat:将 GPT-4 无缝融入 VS Code,极致提升你的编程体验》

你听我说

今天心血来潮,我准备安装下 KubeSphere,于是我打开了 KS 的官网,找到了这篇文章:

看到了吗?第一步是“Prepare a Linux Machine”。我相信很多人都有过这样的需求:

“我需要一台 Linux 机子,系统是 xxx,规格配置是 xxx,网络要求是 xxx,预装软件是 xxx……”

但是我们的 PC 基本都是 Mac or Windows,我们也不希望将一些重量级,服务器端部署的应用跑到自己的 PC 上。这时候要么你的公司有成熟的运维体系,你只要提需求,或者走流程,就有人帮你准备好 Linux 环境;要么,你和我一样,手里有一个 AWS 账号,然后自力更生。(如果你更惨一点,只能在本地倒腾虚拟机,咳咳,哥们珍重。)

AWS 上创建一个合适的 EC2 实例,这个事情说难不难,不过也够让 AWS 新手头疼一会,毕竟至少他得:

  1. 熟悉 AWS 基础概念,基础操作;

  2. 熟悉 EC2,key pair, security group 等概念和基本操作;

  3. 熟悉怎么连接 EC2 实例,知道 Public IP 等概念;

除此之外,也可能一个不小心陷入 IAM、VPC 等复杂的概念里,从入门到放弃。

可能在这个过程中你会遇到一些坑,一个不小心捣鼓失败了,但是碍于“创建一个云主机”这个需求听起来就很“初级”,咱也不好意思请教别人,于是……

没事,以后这类问题一律抛给 DevChat,有事 AI 干。

Hello DevChat

我尝试告诉 DevChat 我的需求和现状,让 DevChat 给出解决方案。

DevChat 是一个对接了 GPT-4 的 VS Code 插件

第一轮

  • My prompt
我需要一个 EC2 实例用于部署单机版的 KubeSphere,这个实例的要求是:
1. 系统是 Ubuntu 22.04;
2. 规格不小于:2 CPU cores, 4 GB memory, and 40 GB disk space;
3. 可以用 ssh 连接;
4. 所有端口都可以从公网访问;

请给出创建这个 EC2 实例和其所需的 ssh key 对应的 Terraform 配置。
  • DevChat 给出了它的解决方案(直接点“Insert Code”可以插入这段代码):

  • DevChat 给出的完整回答:

首先,我们需要明确以下需求:

  • 创建一个 EC2 实例,用于部署单机版的 KubeSphere。

  • EC2 实例的操作系统需要是 Ubuntu 22.04。

  • EC2 实例的规格需要至少为:2 CPU cores, 4 GB memory, and 40 GB disk - space。

  • EC2 实例需要能够通过 ssh 连接。

  • EC2 实例的所有端口都需要能够从公网访问。

以下是创建 EC2 实例和其所需的 ssh key 对应的 Terraform 配置:

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

resource "aws_key_pair" "deployer" {
  key_name   = "deployer-key"
  public_key = file("~/.ssh/id_rsa.pub")
}

resource "aws_security_group" "allow_all" {
  name        = "allow_all"
  description = "Allow all inbound traffic"

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "kubesphere" {
  ami           = "ami-0dba2cb6798deb6d8" # Ubuntu 22.04 LTS
  instance_type = "t2.medium" # 2 vCPU, 4 GB RAM

  key_name = aws_key_pair.deployer.key_name

  vpc_security_group_ids = [aws_security_group.allow_all.id]

  root_block_device {
    volume_size = 40 # 40 GB disk
  }

  tags = {
    Name = "KubeSphere"
  }
}

注意事项:

  • 请将 region 替换为你的 AWS 区域。

  • 请将 public_key 替换为你的公钥文件路径。

  • ami 是 Ubuntu 22.04 LTS 的 AMI ID,可能会因区域不同而不同,你需要根据你的 AWS 区域进行替换。

  • instance_type 是 EC2 实例的类型,这里选择的是 t2.medium,它有 2 vCPU 和 4 GB RAM。如果你需要更大的规格,可以选择其他类型。

  • volume_size 是根卷的大小,这里设置为 40 GB。如果你需要更大的磁盘空间,可以增加这个值。

  • 这个配置将创建一个安全组,允许所有的入站和出站流量。在生产环境中,你可能需要更严格的安全策略。

第二轮

  • My prompt
你给出的配置看起来整体正确,在此之上我还有几点要求:
1. 我想用 ap-southeast-1 region;
2. 我需要在 EC2 实例创建成功后通过 ssh 登录,所以我需要这个实例的 IP 地址;
3. 你提到我需要注意 AMI ID,但是我不想自己去寻找;我希望你在 Terraform 配置里先查询这个 ID,然后再引用,以确保其正确。
  • DevChat 给出了它的解决方案:

翻车了,看到出现了 focal 我就知道又掉了“GPT-4 的训练数据截止日期是2021年9月”这个坑了。“Focal Fossa”是“Ubuntu 20.04 LTS”版本的代号,而“Ubuntu 22.04 LTS”版本的代号是“Jammy Jellyfish”

第三轮

  • My prompt
你给出的配置看起来基本正确了,AMI ID 的获取方式也正确,但是 Ubuntu 22.04 不是 Focal,而是 Jammy,请再次更新配置。
  • DevChat 有一次给出了它的解决方案(可以点“Replace”直接替换当前文件里的全部代码):

  • DevChat 给出的完整回答:

对不起,我犯了一个错误。Ubuntu 22.04 的代号确实是 Jammy,而不是 Focal。我已经在下面的配置中修正了这个错误:

provider "aws" {
  region = "ap-southeast-1"
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_key_pair" "deployer" {
  key_name   = "deployer-key"
  public_key = file("~/.ssh/id_rsa.pub")
}

resource "aws_security_group" "allow_all" {
  name        = "allow_all"
  description = "Allow all inbound traffic"

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_instance" "kubesphere" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.medium" # 2 vCPU, 4 GB RAM

  key_name = aws_key_pair.deployer.key_name

  vpc_security_group_ids = [aws_security_group.allow_all.id]

  root_block_device {
    volume_size = 40 # 40 GB disk
  }

  tags = {
    Name = "KubeSphere"
  }
}

output "instance_public_ip" {
  description = "The public IP of the KubeSphere instance"
  value       = aws_instance.kubesphere.public_ip
}

注意事项:

  • 请将 public_key 替换为你的公钥文件路径。

  • instance_type 是 EC2 实例的类型,这里选择的是 t2.medium,它有 2 vCPU 和 4 GB RAM。如果你需要更大的规格,可以选择其他类型。

  • volume_size 是根卷的大小,这里设置为 40 GB。如果你需要更大的磁盘空间,可以增加这个值。

  • 这个配置将创建一个安全组,允许所有的入站和出站流量。在生产环境中,你可能需要更严格的安全策略。

  • 在 EC2 实例创建成功后,你可以通过 terraform output instance_public_ip 命令获取其公共 IP 地址。

  • aws_ami 数据源会自动查询最新的 Ubuntu 22.04 LTS (Jammy) AMI ID,你不需要手动查找。

这回看起来差不多了,我的 public_key 确实就在“~/.ssh/id_rsa.pub”里,所以这里也不需要修改,接着就来执行一下这段代码,看能不能出来正确的 EC2 实例吧。

成果检验

  • 依次执行:
terraform init
terraform apply
  • 执行结果:

  • 测试 ssh 登录:

完美。(其实不够完美,差就差在 GPT-4 模型的训练数据不是最新的)

总结一下

  1. 如果 GPT-4 能够每隔几个月就用新数据训练一下,那就太漂亮了;

  2. 要让 GPT-4 给出可用的代码,关键是描述清楚自己的需求;

  3. 人生苦短,少些代码。有事 AI 干,没事***(被和谐了)。

BTW: