基础设施即代码的重要性
基础设施即代码(IaC)是现代DevOps实践的核心,能够将基础设施的配置、部署和管理自动化,提高一致性、可重复性和可维护性。Python项目通过Terraform和Ansible等工具,可以实现云资源的自动化管理、配置的统一管理和环境的快速复制。本文将从Terraform基础到Ansible Playbook,全面介绍基础设施即代码的最佳实践。
Terraform基础
1. AWS基础设施配置
# terraform/main.tf
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "python-app/terraform.tfstate"
region = "us-west-2"
}
}
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Environment = var.environment
Project = "python-app"
ManagedBy = "Terraform"
}
}
}
# 变量定义
variable "aws_region" {
description = "AWS区域"
type = string
default = "us-west-2"
}
variable "environment" {
description = "环境名称"
type = string
default = "production"
}
variable "instance_type" {
description = "EC2实例类型"
type = string
default = "t3.medium"
}
# VPC配置
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
}
}
# 子网配置
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-subnet-${count.index + 1}"
}
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "${var.environment}-private-subnet-${count.index + 1}"
}
}
# 互联网网关
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.environment}-igw"
}
}
# EC2实例
resource "aws_instance" "python_app" {
count = 2
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.private[count.index].id
vpc_security_group_ids = [aws_security_group.app.id]
user_data = <<-EOF
#!/bin/bash
apt-get update
apt-get install -y python3 python3-pip
pip3 install -r /tmp/requirements.txt
systemctl start python-app
EOF
tags = {
Name = "${var.environment}-python-app-${count.index + 1}"
}
}
# 安全组
resource "aws_security_group" "app" {
name = "${var.environment}-app-sg"
description = "Python应用安全组"
vpc_id = aws_vpc.main.id
ingress {
from_port = 8000
to_port = 8000
protocol = "tcp"
cidr_blocks = [aws_vpc.main.cidr_block]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.environment}-app-sg"
}
}
# 数据源
data "aws_availability_zones" "available" {
state = "available"
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
# 输出
output "vpc_id" {
value = aws_vpc.main.id
}
output "instance_ips" {
value = aws_instance.python_app[*].private_ip
}
2. Terraform模块化
# terraform/modules/ec2/main.tf
variable "instance_count" {
type = number
default = 1
}
variable "instance_type" {
type = string
default = "t3.micro"
}
variable "subnet_ids" {
type = list(string)
}
variable "security_group_ids" {
type = list(string)
}
resource "aws_instance" "this" {
count = var.instance_count
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = var.subnet_ids[count.index % length(var.subnet_ids)]
vpc_security_group_ids = var.security_group_ids
tags = {
Name = "python-app-${count.index + 1}"
}
}
output "instance_ids" {
value = aws_instance.this[*].id
}
output "instance_ips" {
value = aws_instance.this[*].private_ip
}
Ansible配置管理
1. 基础Playbook
# ansible/site.yml
---
- name: 部署Python应用
hosts: web_servers
become: yes
vars:
app_user: pythonapp
app_dir: /opt/python-app
python_version: "3.9"
tasks:
# 更新系统包
- name: 更新apt缓存
apt:
update_cache: yes
cache_valid_time: 3600
# 安装Python和依赖
- name: 安装Python和pip
apt:
name:
- python
- python-pip
- python-venv
- build-essential
- libssl-dev
- libffi-dev
state: present
# 创建应用用户
- name: 创建应用用户
user:
name: ""
system: yes
shell: /bin/bash
home: ""
create_home: yes
# 创建应用目录
- name: 创建应用目录
file:
path: ""
state: directory
owner: ""
group: ""
mode: '0755'
# 创建虚拟环境
- name: 创建Python虚拟环境
command: python -m venv /venv
args:
creates: "/venv"
become_user: ""
# 安装Python依赖
- name: 安装Python依赖
pip:
requirements: "/requirements.txt"
virtualenv: "/venv"
virtualenv_python: python
become_user: ""
# 复制应用代码
- name: 复制应用代码
copy:
src: ""
dest: "/"
owner: ""
group: ""
loop:
- app.py
- config.py
notify: restart app
# 创建systemd服务
- name: 创建systemd服务
template:
src: python-app.service.j2
dest: /etc/systemd/system/python-app.service
mode: '0644'
notify:
- reload systemd
- restart app
# 启动服务
- name: 启动并启用服务
systemd:
name: python-app
enabled: yes
state: started
daemon_reload: yes
handlers:
- name: reload systemd
systemd:
daemon_reload: yes
- name: restart app
systemd:
name: python-app
state: restarted
2. Ansible角色
# ansible/roles/python-app/tasks/main.yml
---
- name: 安装系统依赖
apt:
name:
- python
- python-pip
- python-venv
state: present
- name: 创建虚拟环境
command: python -m venv
args:
creates: ""
- name: 安装Python依赖
pip:
requirements: ""
virtualenv: ""
- name: 复制应用文件
copy:
src: ""
dest: "/"
loop: ""
- name: 确保服务运行
systemd:
name: ""
enabled: yes
state: started
Python与基础设施自动化
1. Terraform Python Provider
# scripts/terraform_manager.py
import subprocess
import json
import os
class TerraformManager:
"""Terraform管理器"""
def __init__(self, working_dir='terraform'):
self.working_dir = working_dir
os.chdir(working_dir)
def init(self):
"""初始化Terraform"""
result = subprocess.run(
['terraform', 'init'],
capture_output=True,
text=True
)
return result.returncode == 0
def plan(self, var_file=None):
"""生成执行计划"""
cmd = ['terraform', 'plan', '-out=tfplan']
if var_file:
cmd.extend(['-var-file', var_file])
result = subprocess.run(
cmd,
capture_output=True,
text=True
)
return result.returncode == 0, result.stdout
def apply(self, auto_approve=False):
"""应用配置"""
cmd = ['terraform', 'apply']
if auto_approve:
cmd.append('-auto-approve')
else:
cmd.append('tfplan')
result = subprocess.run(
cmd,
capture_output=True,
text=True
)
return result.returncode == 0, result.stdout
def output(self):
"""获取输出值"""
result = subprocess.run(
['terraform', 'output', '-json'],
capture_output=True,
text=True
)
if result.returncode == 0:
return json.loads(result.stdout)
return {}
def destroy(self, auto_approve=False):
"""销毁资源"""
cmd = ['terraform', 'destroy']
if auto_approve:
cmd.append('-auto-approve')
result = subprocess.run(
cmd,
capture_output=True,
text=True
)
return result.returncode == 0
# 使用示例
if __name__ == "__main__":
tf = TerraformManager()
# 初始化
if tf.init():
print("Terraform初始化成功")
# 计划
success, plan_output = tf.plan()
if success:
print("执行计划生成成功")
print(plan_output)
# 应用(需要确认)
# success, apply_output = tf.apply(auto_approve=False)
# 获取输出
outputs = tf.output()
print(f"输出值: {outputs}")
2. Ansible Python API
# scripts/ansible_manager.py
from ansible.playbook import PlayBook
from ansible.inventory import Inventory
from ansible import callbacks
from ansible import utils
import ansible.runner
class AnsibleManager:
"""Ansible管理器"""
def __init__(self, inventory_file='ansible/hosts'):
self.inventory_file = inventory_file
def run_playbook(self, playbook_file, extra_vars=None):
"""运行Playbook"""
inventory = Inventory(self.inventory_file)
playbook = PlayBook(
playbook=playbook_file,
inventory=inventory,
extra_vars=extra_vars or {}
)
stats = playbook.run()
return stats
def run_ad_hoc(self, hosts, module, args):
"""运行临时命令"""
runner = ansible.runner.Runner(
module_name=module,
module_args=args,
pattern=hosts,
inventory=Inventory(self.inventory_file)
)
result = runner.run()
return result
# 使用示例
if __name__ == "__main__":
ansible = AnsibleManager()
# 运行Playbook
stats = ansible.run_playbook(
'ansible/site.yml',
extra_vars={'environment': 'production'}
)
# 运行临时命令
result = ansible.run_ad_hoc(
hosts='web_servers',
module='ping',
args=''
)
print(f"Ping结果: {result}")
总结
基础设施即代码的关键要点:
- Terraform:云资源的声明式管理和版本控制
- Ansible:配置管理和应用部署自动化
- 模块化设计:可重用的基础设施模块
- 状态管理:远程状态存储和锁定
- 变量管理:环境变量和敏感信息管理
- Python集成:通过Python脚本自动化基础设施操作
- 最佳实践:代码审查、测试、渐进式部署
掌握这些基础设施即代码技能,可以实现基础设施的自动化管理、环境的快速复制和配置的统一管理,为Python项目提供强大的基础设施支持。
转载请注明:周志洋的博客 » Python DevOps-基础设施即代码详解


