Infrastructure as Code: Terraform, Ansible
Infrastructure as Code: Terraform, Ansible
1)为什么IaC和工具有何不同
Terraform-声明性的orchestrator-IaC:通过提供商创建/修改云基础设施(VPC,K8s,LB,DB,IAM)。管理资源生命周期并存储状态。
Ansible-过程配置-IaC和配置管理:配置主机/软件(软件包、文件、服务),了解应用程序调试、播放和步骤编排。无代理(SSH/WinRM),具有任务等效性。
组合:Terraform-"平台由何而来",Ansible-"如何配置和运行"。
2)存储库和图层的结构
我们推荐3层:1.基金会(着陆区):网络,IAM,KMS,基本期刊/监视。
2.平台:Kubernetes集群,基地,队列,观察堆栈。
3.Workloads:空间/空间,服务帐户,政策,configs.
Repo:- 'iac/terraform/'-模块和环境('modules/','envs/')。
- "iac/ansible/"-角色("roles/"),花花公子("playbooks/"),库存("inventories/")。
- "policies/"-OPA/Conftest规则。
- "pipelines/"-CI/CD脚本(lint/plan/apply/test)。
3)Terraform: 模块,状态,环境
3.1个模块
较小,重新使用:"vpc","eks","rds","redis","alb","iam-role"。
输入→ 'variables。tf',出口→ 'outputs。tf",版本-通过模块/git标签注册表。
hcl module "vpc" {
source = "git::ssh://git@repo/iac. git//modules/vpc? ref=v1. 6. 0"
name = "prod-core"
cidr = "10. 0. 0. 0/16"
azs = ["eu-central-1a","eu-central-1b"]
}
3.2个状态(状态)
远程后端(S3/GCS+DynamoDB/LockTable)+锁定。
周围分开: 'prod。tfstate`, `staging.tfstate`.
状态漂移:按时间表在CI中的"terraform plan";漂移时的异常。
Backend示例:hcl terraform {
backend "s3" {
bucket = "iac-state"
key = "prod/network/terraform. tfstate"
region = "eu-central-1"
dynamodb_table = "iac-locks"
encrypt = true
}
}
3.3 Workspaces / Envs
变体:- 单独的"envs/prod","envs/stage"目录(生动)。
- Workspaces用于轻微的变化,但避免混合秘密。
- 通过"tfvars":"prod的参数。tfvars`, `stage.tfvars`.
4)Ansible: 角色,库存,相等性
4.1角色和花花公子
Galaxy标准:
roles/
nginx/
tasks/main. yml templates/.j2 handlers/main. yml defaults/main. yml playbooks/
site. yml
花花公子示例:
yaml
- hosts: web become: true roles:
- role: nginx vars:
nginx_listen_port: 8080
4.2库存和动态
`inventories/prod/hosts.yml'+变量'group_vars/host_vars'。
动态清单: 'aws_ec2','gcp_compute','kubernetes。core`.
4.3相似性
在可能的情况下使用模块(不使用"外壳")。
干运行的"changed_when'/'check_mode"。
手柄仅在更改时反射。
5)秘密和伪装
Terraform:通过"sensitive=true"分泌值;秘密本身-不在状态(存储在AWS Secrets Manager/HashiCorp Vault/KMS中,并引用数据源)。
Ansible:用于变量加密的Vault("ansible-vault encrypt"),与HashiCorp Vault/KMS集成。
GitOps:在单独的回购/存储中的秘密,通过least-privilege访问。
6)政策与合规性(政策即代码)
OPA/Conftest for Terraform Planns:禁止SG开放的公共S3、未消耗的资源(标签)。
Terraform Cloud/Enterprise-Sentinel作为替代品。
Ansible Lint:风格和安全(没有"sudo:yes",不需要raw-shell)。
rego package terraform. security
deny[msg] {
input. resource_type == "aws_security_group_rule"
input. values. cidr_blocks[_] == "0. 0. 0. 0/0"
input. values. from_port == 22 msg:= "SSH from 0. 0. 0. 0/0 is forbidden"
}
7) IaC测试
Terraform:"tflint","tfsec"/"checkov",Terratest(Go)用于集成检查。
Ansible:"ansible-lint",Molecule(+Docker/Podman/EC2)用于角色验证。
应用后空白测试:HTTP probes,端口/过程,权限。
8) CI/CD и GitOps
管道(在Pull/Merge Request上):1.Lint/Sec: tflint, tfsec/checkov, ansible-lint.
2.计划:"terraform计划",其中包含人工制品的发布(MR中的评论)。
3.Policy Gate: Conftest/Sentinel.
4.Apply (manual/approved):仅在带有工件签名的主页上。
5.Ansible deploy:舞台上的"--check",然后舞台上的"--diff"。
6.Post-checks: 合成/Probe, dashboard发布注释。
GitOps:
将宣言作为真理的来源;Argo CD/Flux用于Kubernetes,但基本集群/原语是通过Terraform进行的。
9)Kubernetes,网络,DB的模式
9.1 Kubernetes
Terraform: EKS/GKE/AKS群集、节点、IAM、StorageClass, LB。
Ansible:准备AMI/堡垒、映像/存储库、安装后 (日志记录器/代理程序/OTel)。
9.2个网络和外围
Terraform:VPC/子网/NAT/Transit-Gateway/WAF,路线。
不可能:NGINX/Envoy/HAProxy、TLS、WAF configs规则。
9.3个基地/缓存/队列
Terraform:RDS/CloudSQL参数组,Redis/ElastiCache,Kafka/MSK。
Ansible:加热缓存、进行迁移、设置备份/代理。
10)Configs示例
10.1 Terraform — RDS PostgreSQL + SG
hcl module "db" {
source = "terraform-aws-modules/rds/aws"
engine = "postgres"
engine_version = "15. 4"
instance_class = "db. m6g. large"
allocated_storage = 100 name = "core"
username = var. db_user password = var. db_password # см. secret data source vpc_security_group_ids = [module. db_sg. security_group_id]
multi_az = true backup_retention = 7
}
module "db_sg" {
source = "terraform-aws-modules/security-group/aws"
name = "db-core"
vpc_id = module. vpc. vpc_id ingress_cidr_blocks = ["10. 0. 0. 0/8"]
ingress_rules = ["postgresql-tcp"]
}
10.2 Terraform-数据源秘密
hcl data "aws_secretsmanager_secret_version" "db" {
secret_id = "prod/db/core"
}
variable "db_password" {
type = string sensitive = true default = jsondecode(data. aws_secretsmanager_secret_version. db. secret_string). password
}
10.3 Ansible-postgresql客户端角色(片段)
yaml
- name: Install packages apt:
name: [ "postgresql-client-15" ]
state: present update_cache: yes
- name: Create. pgpass copy:
dest: /home/deploy/.pgpass mode: '0600'
content: "{{ db_host }}:5432:core:{{ db_user }}:{{ db_password }}"
no_log: true
- name: Smoke query shell: psql -h {{ db_host }} -U {{ db_user }} -d core -c "select 1"
register: psql_out changed_when: false
10.4 Ansible-带节奏的NGINX
yaml
- name: Deploy nginx. conf template:
src: templates/nginx. conf. j2 dest: /etc/nginx/nginx. conf notify: Restart nginx
- name: Ensure nginx running service:
name: nginx state: started enabled: true
handlers:
- name: Restart nginx service: { name: nginx, state: restarted }
11)漂移和合规管理
只读密钥中的周期性"terraform plan";分散时会产生滴答声。
Ansible -check是关键角色(审计模式)的时间表。
报告:未执行OPA/Conftest策略,无标签/备份/监视资源。
12)可观察性和审计
"terraform apply"徽标和计划工件-保存到对象存储中。
Ansible:"callback_plugins"(json)→ 中央日志/ELK;包括job ID、commit SHA、trace_id。
度量标准:计划/播放时间、更改频率、测试覆盖范围。
13)安全性
模块/角色签名或固定标签/哈希。
最低限度的IAM权利("计划"≠"应用"),将CI和人类应用者的角色分开。
状态/逻辑加密,模块/角色私有注册表。
VCS中的"no plaintext secrets"策略,密码扫描仪(gitleaks/trufflehog)。
14)反模式
单个Terraform怪物模块"全部";没有模块版本。
本地'terraform。tfstate"和没有锁定。
IaC顶部的云端手动编辑→永恒的漂移。
Ansible "shell"/"command"代替模块(打破幂等)。
无组/变量的"单一文件"清单,prod/stage混合。
vars/存储库中的秘密,缺少Vault/KMS。
没有计划或没有同行评审的应用。
15)实施清单(0-45天)
0-10天
配置远程后端/锁定,分解Terraform模块。
启用tflint/tfsec/checkov,ansible-lint;商定资源标签/标签。
为NGINX/Agent/Logers担任Ansible角色;安排库存。
11-25天
为关键模块/角色添加Conftest/OPA、Terratest和Molecule。
CI: MR上的"计划",计划的人工制品,带有应用程序的手动应用程序;Ansible `--check` на stage.
保密-存储集成(Vault/KMS/Secrets Manager)。
26-45天
Drift探测器计划中的自动计划,策略报告。
具有转换的模块/角色目录;README文档。每个人都有md'。
GitOps:版本注释,监视捆绑和警报门。
16)成熟度量
具有远程状态和湖泊的环境的百分比为100%。
具有测试(Terratest/Molecule)的模块/角色比例≥ 70%。
从MR到apply (prod)的平均时间是小时,不是天。
零"手动漂移"(所有更改均通过MR进行)。
100%的关键资源由Policy as Code(标签、加密、备份)覆盖。
17)结论
Terraform设置了可预测,可重复的基础架构;Ansible使主机和服务达到所需的状态。添加Policy as Code、具有位置的远程状态、测试、秘密管理和CI/CD和plan→review→apply-并且您的IaC轮廓将变得可管理、安全且快速,并且版本具有原子性和可逆性。