本文目录导读:

- 使用Pulumi Python SDK直接配置
- 使用配置文件(Pulumi.yaml + Pulumi.{stack}.yaml)
- Python脚本动态生成配置
- 使用模板引擎生成配置
- 使用配置生成脚本自动化
- 使用建议
我来介绍几种使用Python脚本生成Pulumi配置的方法:
使用Pulumi Python SDK直接配置
import pulumi
import pulumi_aws as aws
# 基本配置
config = pulumi.Config()
project_name = config.require("project_name")
environment = config.get("environment", "dev")
# 创建资源
bucket = aws.s3.Bucket(
f"{project_name}-{environment}",
acl="private",
tags={
"Environment": environment,
"Project": project_name
}
)
pulumi.export("bucket_name", bucket.id)
使用配置文件(Pulumi.yaml + Pulumi.{stack}.yaml)
Pulumi.yaml (项目配置)
name: my-project runtime: python description: My Pulumi project # 可以在Python中读取 config: aws:region: us-west-2
Pulumi.dev.yaml (环境配置)
config: my-project:project_name: my-app my-project:environment: dev my-project:instance_size: t2.micro aws:region: us-west-2
Python脚本动态生成配置
import json
import yaml
from pathlib import Path
class PulumiConfigGenerator:
def __init__(self, project_name: str):
self.project_name = project_name
self.config = {}
def load_from_json(self, file_path: str):
"""从JSON文件加载配置"""
with open(file_path, 'r') as f:
data = json.load(f)
self.config.update(data)
def load_from_env(self, prefix: str = "PULUMI_"):
"""从环境变量加载配置"""
import os
for key, value in os.environ.items():
if key.startswith(prefix):
config_key = key.replace(prefix, "").lower()
self.config[config_key] = value
def add_config(self, key: str, value, namespace: str = None):
"""添加配置项"""
if namespace:
key = f"{namespace}:{key}"
self.config[key] = value
def generate_config_files(self, output_dir: str = "./"):
"""生成Pulumi配置文件"""
# 生成Pulumi.yaml
project_config = {
"name": self.project_name,
"runtime": "python",
"description": f"Pulumi project for {self.project_name}",
"config": {
"aws:region": "us-west-2"
}
}
with open(f"{output_dir}/Pulumi.yaml", 'w') as f:
yaml.dump(project_config, f, default_flow_style=False)
# 生成环境配置文件
env_config = {
"config": self.config
}
with open(f"{output_dir}/Pulumi.dev.yaml", 'w') as f:
yaml.dump(env_config, f, default_flow_style=False)
def generate_pulumi_code(self, resources: list):
"""生成Pulumi Python代码"""
code_lines = [
"import pulumi",
"import pulumi_aws as aws",
"",
"# 配置"
]
# 添加配置读取
for key, value in self.config.items():
code_lines.append(f'config = pulumi.Config("{self.project_name}")')
code_lines.append(f'{key} = config.require("{key}")')
break
code_lines.append("")
code_lines.append("# 创建资源")
# 添加资源创建代码
for resource in resources:
code_lines.extend(self._generate_resource_code(resource))
return "\n".join(code_lines)
def _generate_resource_code(self, resource: dict) -> list:
"""生成单个资源的代码"""
code = []
if resource["type"] == "s3_bucket":
code.append(f'{resource["name"]} = aws.s3.Bucket(')
code.append(f' "{resource["name"]}",')
code.append(f' acl="{resource.get("acl", "private")}",')
if "tags" in resource:
code.append(" tags={")
for key, value in resource["tags"].items():
code.append(f' "{key}": "{value}",')
code.append(" },")
code.append(")")
code.append(f'pulumi.export("{resource["name"]}_id", {resource["name"]}.id)')
return code
# 使用示例
def main():
generator = PulumiConfigGenerator("my-project")
# 加载配置
generator.add_config("project_name", "my-app")
generator.add_config("environment", "production")
generator.add_config("instance_count", 3, "my-project")
# 生成配置文件
generator.generate_config_files("./output")
# 生成Python代码
resources = [
{
"type": "s3_bucket",
"name": "app-bucket",
"acl": "private",
"tags": {
"Environment": "production",
"Project": "my-app"
}
}
]
python_code = generator.generate_pulumi_code(resources)
with open("./output/__main__.py", 'w') as f:
f.write(python_code)
if __name__ == "__main__":
main()
使用模板引擎生成配置
from jinja2 import Template
import json
import yaml
class TemplateBasedGenerator:
def __init__(self, template_dir: str):
self.template_dir = template_dir
def generate_from_json(self, json_config: str, template_file: str):
"""从JSON模板生成配置"""
with open(json_config, 'r') as f:
config = json.load(f)
with open(f"{self.template_dir}/{template_file}", 'r') as f:
template_content = f.read()
template = Template(template_content)
rendered = template.render(**config)
return rendered
def generate_pulumi_yaml(self, config: dict):
"""生成Pulumi YAML配置"""
pulumi_config = {
"name": config.get("project_name"),
"runtime": "python",
"description": config.get("description", ""),
"config": {
f"{config.get('project_name')}:environment": config.get("environment", "dev"),
"aws:region": config.get("region", "us-west-2")
}
}
return yaml.dump(pulumi_config, default_flow_style=False)
# 使用示例
def generate_complex_config():
config_data = {
"project_name": "my-app",
"environment": "production",
"region": "us-east-1",
"vpc": {
"cidr": "10.0.0.0/16",
"subnets": ["10.0.1.0/24", "10.0.2.0/24"]
},
"instances": [
{"name": "web-1", "type": "t3.medium", "count": 2},
{"name": "db-1", "type": "r5.large", "count": 1}
]
}
generator = TemplateBasedGenerator("./templates")
pulumi_config = generator.generate_pulumi_yaml(config_data)
with open("Pulumi.prod.yaml", 'w') as f:
f.write(pulumi_config)
if __name__ == "__main__":
# 运行生成器
generate_complex_config()
使用配置生成脚本自动化
#!/usr/bin/env python3
"""
自动化Pulumi配置生成脚本
"""
import argparse
import json
import sys
from pathlib import Path
def parse_args():
parser = argparse.ArgumentParser(description='Generate Pulumi configurations')
parser.add_argument('--project', required=True, help='Project name')
parser.add_argument('--environment', required=True, help='Environment name')
parser.add_argument('--config-file', help='JSON configuration file')
parser.add_argument('--output-dir', default='.', help='Output directory')
parser.add_argument('--generate-code', action='store_true', help='Generate Python code')
return parser.parse_args()
def generate_config(args):
"""主配置生成函数"""
config = {
"project_name": args.project,
"environment": args.environment
}
# 从文件加载额外配置
if args.config_file:
with open(args.config_file, 'r') as f:
extra_config = json.load(f)
config.update(extra_config)
# 生成Pulumi YAML配置
pulumi_config = {
"name": config["project_name"],
"runtime": "python",
"description": f"{config['project_name']} - {config['environment']}",
"config": {
"aws:region": config.get("region", "us-west-2"),
f"{config['project_name']}:environment": config['environment']
}
}
# 写入配置文件
output_path = Path(args.output_dir)
output_path.mkdir(parents=True, exist_ok=True)
config_file = output_path / f"Pulumi.{args.environment}.yaml"
with open(config_file, 'w') as f:
json.dump(pulumi_config, f, indent=2)
print(f"Configuration generated: {config_file}")
if args.generate_code:
# 生成Python代码
generate_python_code(config, output_path)
def generate_python_code(config, output_path):
"""生成Python初始代码"""
code = f"""import pulumi
import pulumi_aws as aws
# Project: {config['project_name']}
# Environment: {config['environment']}
config = pulumi.Config("{config['project_name']}")
environment = config.require("environment")
# TODO: Add your resources here
# Example:
# bucket = aws.s3.Bucket(
# f"{{config['project_name']}}-{{environment}}",
# acl="private"
# )
pulumi.export("project", "{config['project_name']}")
pulumi.export("environment", environment)
"""
code_file = output_path / "__main__.py"
with open(code_file, 'w') as f:
f.write(code)
print(f"Python code generated: {code_file}")
if __name__ == "__main__":
args = parse_args()
generate_config(args)
使用建议
- 配置文件方式:使用
Pulumi.{stack}.yaml文件管理环境特定配置 - 代码方式:直接在Python中使用
pulumi.Config()读取配置 - 动态生成:使用脚本根据外部数据源(如JSON、环境变量)生成配置
- 模板方式:使用Jinja2等模板引擎生成复杂的配置结构
这些方法可以根据你的具体需求组合使用,实现灵活的Pulumi配置管理。