教你白嫖 Github Pages 和 Google Cloud VM ——Ansible 与 Terraform 自动化部署(中)

上一篇的疯狂开端之后,第二天我继续研究部署 docker 的办法(这样就能和早些时候联系上了!)

这篇总体上来说还算顺利(毕竟没干什么重要事情

Terraform 创建 VM instance

首先我们邀请 chatGPT 老师给我们一个大体的框架:

1. Setup Prerequisites
- Google Cloud SDK installed and authenticated (gcloud auth application-default login)
- Terraform installed
- A GCP project with billing enabled
- Create a service account with Compute Admin permissions and generate a JSON key
2. Terraform Configuration to Create GCE Instance
Directory structure:
gcp-deploy/
├── terraform/
│   ├── main.tf
│   ├── variables.tf
│   └── terraform.tfvars
...

讲真的,要我对着 google cloud 文档看这些然后自己摸索的话,真的可能会谢(警惕不当网络用语

有几个注意点 吐槽

  • gcloud 有 AUR 包,安装还算方便。但是好大……(夺少?!666 MB?!
$ yay gcloud
1 aur/google-cloud-cli 523.0.1-1 (+191 1.27) 
    A set of command-line tools for the Google Cloud Platform. Includes gcloud (with beta and alpha commands), gsutil, and bq.
==> Packages to install (eg: 1 2 3, 1-3 or ^4)
==> 1
Packages (1) google-cloud-cli-523.0.1-1
Total Installed Size:  666.70 MiB
  • 用了 Privacy 的虚拟卡和 随机地址生成器
  • 稍微改了一下 terraform 文件夹下面的一些配置,不知道后面会不会炸掉(
  • 后来想到一个偷懒的办法,就是拿现有的 VM 复制一份,然后配置界面会有 Equivalent Code 的按钮,这时候可以看到 Terraform 的配置文件(可以抄作业了!
  • 好想吐槽为什么 apply 只要一分钟但是 destroy 就要五分钟啊?!
  • 总算部署上了,过两天看看 billing 的数目对不对

Ansible 部署代码文件

连接 host

  • ansible 怎么也这么庞大……
$ yay ansible
2 extra/ansible-core 2.18.6-1 (3.1 MiB 20.4 MiB) 
    Radically simple IT automation platform
1 extra/ansible 11.6.0-1 (38.0 MiB 531.6 MiB) 
    Official assortment of Ansible collections

还好有 core 包,其它插件可以后面慢慢加(有点像 microconda 和 anaconda?

  • 发现 ssh 一直登录不上去,想起来还要配置防火墙……大概是这样(只 ssh 的话就只要 tcp:22
resource "google_compute_firewall" "fw1" {
  name    = "fw1"
  network = google_compute_network.custom_network.id  # 这里填具体的网络 id
  priority = 1000
  direction = "INGRESS"
  allow {
    protocol = "all"
  }
  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["allow-all-ingress"]
}
  • 折腾半天 ansible 连不上 ssh,才发现 chatGPT 生成的配置文件使用了十年前的 id_rsa(但是我忘记 passphrase 了捂脸),所以导致一直登录不了。好在重新生成加 terraform apply 改 pub key 还算方便
  • 准备检验网页的时候突然想起来还要在 cloudflare 那里注册上 ip (
  • 中间 chatGPT 生成的 task 还不是特别可靠,会出现什么文件夹木有啊,tar 解包路径错误的问题……

certbot

(老鼠配音)你好~

倒也没有特别复杂,唯一一个坑就是要指定 nginx 的 binary 位置:

certbot --nginx --nginx-ctl /usr/sbin/nginx

好吧,其实还有一个坑是找不到 notify: Restart nginx,明明就在旁边的 handler 文件夹里 = = 所以最后索性每次手动检查 nginx reload

还学到了一些别的奇技淫巧,用来提取子域名

- name: Extract sub_domain from inventory_hostname
  set_fact:
    sub_domain: "{{ inventory_hostname.split('.')[0] }}"

这样就可以在nginx conf j2这里使用了

server {
    listen 80;
    server_name {{ sub_domain }}.{{ apex_domain }};

docker

nginx 官方维护了一个smoke test,看起来还不错。配置了一下,发现 http 可以看到但是 https不行……后来发现是之前配置的 hugo 把域名撞车了(狗带

效果如下图

bot blocker

还安装了 fail2ban 和 nginx-ultimate-bad-bot-blocker(这个名字真的很长很中二)。但是 somehow 这个 blocker 并不会对 redirect 流量的 vhost 起效果(即没有 root 的断语,见 这里),就,觉得蛮奇怪的。

docker app 上传和下载备份文件

我又让 chatGPT 老师帮我设计了一个可以上传 docker volume+自动备份+rotate 清理空间的流程。看起来似乎还可以。

中间在纠结说是签一个 wildcard 证书还是每个 app 自己搞个 certbot 去签名。第一种方案有个坑,是 wildcard 签名必须用 dns 验证,所以还要多加文件;最麻烦的是 chrome somehow 认为 wildcard 不安全……呃那还是第二种吧。

小结

现在的结构树大概是这个样子

.
├── _template ...
├── anglerfish ...
├── beluga
│   ├── ansible
│   │   ├── inventory
│   │   ├── playbook-miniflux.yml
│   │   ├── playbook-setup.yml
│   │   ├── README
│   │   └── roles
│   │       ├── container-backup ...
│   │       ├── container-deploy ...
│   │       ├── container-reverse-proxy ...
│   │       ├── container-start ...
│   │       ├── setup-bot-blocker ...
│   │       └── setup-common ...
│   └── terraform
│       ├── dns ...
│       └── instance
│           ├── main.tf
│           ├── terraform.tfvars
│           └── variables.tf
├── docker
│   └── miniflux
│       ├── compose.yaml.j2
│       └── volume.tar.gz
├── README.md
└── secrets
     ├── ansible.yml
     ├── cloudflare_dns.json
     └── gcp.json

这里我拿鱼的名字来命名每一台 白嫖 的 instance 了(哈哈哈

上面的这些东西我稍微整理了一下放在了 owen8877/terraform-ansible-playground 这破玩意儿不会有人来看的吧