我们开发者是一群懒惰的人。但这是那种好的懒惰——促使我们自动化一切,以便我们可以专注于有趣的事情(比如讨论制表符与空格)。这就是基础设施即代码的用武之地,它确实不负众望:

  • 可复现性:将整个基础设施放在一个 git 仓库中。服务器的版本控制?当然要有!
  • 可扩展性:需要 100 台服务器而不是 10 台?改个数字,点击应用,瞬间扩展。
  • 一致性:再也没有“在我机器上能运行”的借口。如果在预发布环境中能运行,那么在生产环境中也能运行(大多数情况下)。
  • 可审计性:每次更改都被跟踪,每个配置都有文档记录。未来的你会感谢现在的你。

Terraform:基础设施的低语者

Terraform 就像那个总是知道哪里有最优惠的朋友——只不过它不是便宜的演唱会门票,而是跨多个提供商配置云资源。以下是它在 IaC 领域中为何如此出色的原因:

  • 提供商无关性:AWS、Azure、GCP 或你自己的数据中心——Terraform 不会有偏见。
  • 声明式语法:你说出你想要的,Terraform 会找出如何实现。简直是魔法!
  • 状态管理:跟踪你的基础设施的当前状态,所以你不必费心(因为谁有时间去做这些呢?)。

让我们通过一个简单的例子来看看 Terraform 的实际应用:


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

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  tags = {
    Name = "Web Server"
  }
}

就这样,你就有了一个崭新的 EC2 实例。但等等,还有更多!

Ansible:配置大师

虽然 Terraform 在设置基础设施方面表现出色,但 Ansible 在配置方面更胜一筹。可以把 Ansible 想象成 Terraform 的室内设计师。它确保你的服务器不仅建成,而且装饰得当,准备就绪。

以下是 Ansible 在我们的 IaC 配方中为何是秘密武器的原因:

  • 无代理:无需在目标机器上安装任何东西。只需 SSH 即可。
  • 基于 YAML:谁不喜欢一个好的 YAML 文件呢?(别回答这个问题。)
  • 幂等性:你可以多次运行你的 playbook——Ansible 只在需要时进行更改。

让我们看看一个配置我们新创建的 EC2 实例的 Ansible playbook:


---
- hosts: web_servers
  become: yes
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Start Nginx
      service:
        name: nginx
        state: started

就这样,你的服务器比你说“DevOps”还快地提供网页服务。

动态双雄:Terraform + Ansible

现在,魔法即将发生。通过结合 Terraform 和 Ansible,你可以创建一个比新打蜡的数据中心地板还要顺滑的部署管道。以下是一个高层次的工作流程:

  1. 使用 Terraform 配置你的基础设施(VPC、EC2 实例、负载均衡器等)
  2. 输出创建的资源的 IP 地址或 DNS 名称
  3. 从 Terraform 输出动态生成 Ansible 清单
  4. 针对该清单运行 Ansible playbook 以配置你的服务器

这就像观看一场美丽的比特和字节的芭蕾舞。但我们不要太诗意——我们是来写代码的,不是来写十四行诗的。

让你的部署坚不可摧

现在我们已经掌握了基础知识,让我们来谈谈如何让你的部署如此坚固,以至于它们可以在核爆(或特别激进的 QA 团队)中幸存下来。

1. 版本控制一切

我指的是一切。你的 Terraform 配置、Ansible playbook,甚至你的 README 文件。如果它不在 git 中,那它就不存在。

2. 使用模块和角色

不要重复自己。使用 Terraform 模块和 Ansible 角色来创建可重用、可组合的基础设施和配置片段。

3. 实施强大的状态管理

将你的 Terraform 状态文件远程存储(例如在 S3 存储桶中)并使用状态锁定。相信我,你不想让两个人同时应用更改。

4. 自动化测试

使用像 Kitchen-Terraform 这样的工具来测试你的基础设施代码,使用 Molecule 来测试 Ansible 角色。因为手动测试基础设施就像看油漆干一样无聊。

5. 实施持续集成/持续部署(CI/CD)

自动化你的整个部署管道。每次提交都应触发构建、测试,甚至可能是部署。像 Jenkins、GitLab CI 或 GitHub Actions 这样的工具是你的好朋友。

真实案例:部署高可用性 Web 应用

让我们用一个更复杂的例子来把这一切结合在一起。我们将使用 Terraform 和 Ansible 部署一个高可用性的 Web 应用程序。

首先,我们的 Terraform 配置:


# 创建一个 VPC
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "Main VPC"
  }
}

# 创建公共子网
resource "aws_subnet" "public" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]
  tags = {
    Name = "Public Subnet ${count.index + 1}"
  }
}

# 创建 EC2 实例
resource "aws_instance" "web" {
  count         = 2
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.public[count.index].id
  tags = {
    Name = "Web Server ${count.index + 1}"
  }
}

# 创建负载均衡器
resource "aws_lb" "web" {
  name               = "web-lb"
  internal           = false
  load_balancer_type = "application"
  subnets            = aws_subnet.public[*].id
}

# 输出负载均衡器的 DNS 名称
output "lb_dns_name" {
  value = aws_lb.web.dns_name
}

现在,让我们用 Ansible 配置这些实例:


---
- hosts: web_servers
  become: yes
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Copy custom Nginx config
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: Restart Nginx

    - name: Copy web content
      copy:
        src: files/index.html
        dest: /var/www/html/index.html

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

通过这些配置,你刚刚部署了一个负载均衡的高可用性 Web 应用程序。但我们还没有完成!

监控和日志:因为看不见的东西可能会伤害你

现在我们有了坚不可摧的基础设施,我们需要密切关注它。进入监控和日志:

  • Prometheus:用于指标收集和警报
  • Grafana:用于美观且信息丰富的仪表板
  • ELK 堆栈(Elasticsearch、Logstash、Kibana):用于集中日志记录

你可以使用 Terraform 来设置这些监控工具,并使用 Ansible 来配置你的应用程序以将日志和指标发送给它们。这就像给你的基础设施做一个全面的健康检查,但没有不舒服的纸质长袍。

安全性:因为黑客从不休息(你的防御也不应该)

在 IaC 中,安全性不仅重要——它至关重要。以下是一些保持你的基础设施如同诺克斯堡般安全的提示:

  • 使用安全组:Terraform 使定义和管理安全组变得容易。锁定那些端口!
  • 加密敏感数据:使用像 Ansible Vault 这样的工具来加密敏感变量。
  • 实施 IAM 角色:使用 Terraform 创建和管理具有最小权限原则的 IAM 角色。
  • 定期安全审计:使用像 tfsec 这样的工具来检查 Terraform 的安全配置错误,使用 ansible-lint 来检查 Ansible 的安全配置错误。

扩展:因为成功不应该破坏你的基础设施

IaC 的一个美妙之处在于它让你轻松扩展。使用 Terraform,扩展通常只需更改一个数字并重新应用。但请记住,能力越大,责任越大(以及可能更大的 AWS 账单)。

考虑使用 Terraform 实现自动扩展组:


resource "aws_autoscaling_group" "web" {
  name                = "web-asg"
  min_size            = 2
  max_size            = 10
  desired_capacity    = 2
  target_group_arns   = [aws_lb_target_group.web.arn]
  vpc_zone_identifier = aws_subnet.public[*].id

  launch_template {
    id      = aws_launch_template.web.id
    version = "$Latest"
  }
}

现在你的应用程序可以在不费力(或不超出预算)的情况下处理流量高峰。

灾难恢复:因为事情总会发生

即使有坚不可摧的部署,灾难仍然可能发生。但有了 IaC,灾难恢复变得更加可控:

  • 多区域部署:使用 Terraform 工作区来管理跨多个区域的部署。
  • 备份和恢复:使用 Terraform 设置数据和基础设施状态的定期备份。
  • 混沌工程:故意引入故障以测试基础设施的弹性。像 Chaos Monkey 这样的工具可以集成到你的 IaC 工作流中。

持续改进:永远在优化

IaC 的世界在不断发展。保持最新的功能和最佳实践:

  • 定期更新你的 Terraform 和 Ansible 版本
  • 参加会议和网络研讨会(或者至少在假装工作时观看录音)
  • 为开源 IaC 项目做贡献(这对灵魂和你的 GitHub 个人资料都有好处)

结论:你现在是 IaC 巫师了

恭喜!你刚刚提升了你的基础设施技能。有了 Terraform 和 Ansible 在你的工具箱中,你现在可以创建、管理和扩展比瑞士手表更可靠的基础设施(而且可能更复杂)。

记住,基础设施即代码不仅仅是一组工具——它是一种心态。它是关于像对待应用程序代码一样对待你的基础设施,进行同样的关心、版本控制和测试。所以去吧,自动化所有事情,愿你的部署永远顺利!

现在,如果你不介意,我有一些服务器要启动。或者也许我只需小憩一下,让我的 IaC 管道完成工作。毕竟,这就是自动化的意义,不是吗?

“预测未来的最佳方式就是创造它。” - Alan Kay

有了基础设施即代码,你不仅是在预测你的基础设施的未来——你是在定义它,版本控制它,并用一个命令部署它。这就是我所说的进步!