如何在AWS CloudFormation中通过UserData实现EC2实例创建时自动部署Python服务脚本
当然可以用UserData实现自动部署!
你完全找对方向了——CloudFormation的UserData就是用来在EC2实例启动时自动执行初始化操作的,包括部署你的Python脚本,不用再手动等堆栈创建完SCP传输。我来一步步帮你实现:
核心思路
你的现有UserData已经在安装Python依赖了,接下来只需要把Python脚本传到实例里,然后配置启动即可。这里有两种常用方案,根据你的场景选:
方案1:用S3存储脚本(推荐,适合长脚本)
这种方法更灵活,脚本更新也方便,步骤如下:
1. 先把Python脚本上传到S3
在你的deploy.sh里添加一行,把脚本传到你的S3桶里(提前创建好S3桶):
# 在deploy.sh中添加,放在创建堆栈的命令之前 aws s3 cp your-python-server-script.py s3://your-bucket-name/scripts/
2. 给EC2实例加S3访问权限
EC2实例需要权限从S3下载脚本,所以要在CloudFormation里创建一个IAM角色:
# 在你的CFN模板里添加以下IAM资源 InstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole # 自定义严格策略(推荐),只允许访问你的脚本桶 Policies: - PolicyName: AccessPythonScriptBucket PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:GetObject Resource: arn:aws:s3:::your-bucket-name/scripts/* InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref InstanceRole
3. 修改EC2实例的配置和UserData
给你的EC2实例关联这个InstanceProfile,然后更新UserData来下载脚本、设置权限并启动:
EC2Instance2: Type: AWS::EC2::Instance Properties: InstanceType: !Ref InstanceType SecurityGroupIds: - !Ref InstanceSecurityGroup KeyName: !Ref KeyName ImageId: !Ref LatestAmiId # 添加InstanceProfile赋予S3访问权限 IamInstanceProfile: !Ref InstanceProfile UserData: Fn::Base64: !Sub | #!/bin/bash # 等待系统初始化完成(按需调整sleep时间) sleep 20 # 更新系统并安装依赖 sudo apt-get update -y sudo apt-get install python3-pip python3-flask awscli -y # 从S3下载Python脚本到实例 aws s3 cp s3://your-bucket-name/scripts/your-python-server-script.py /home/ubuntu/ # 设置脚本执行权限 sudo chmod +x /home/ubuntu/your-python-server-script.py # 后台启动脚本(用nohup临时运行,生产环境推荐配置systemd服务) nohup python3 /home/ubuntu/your-python-server-script.py > /home/ubuntu/server.log 2>&1 &
方案2:直接嵌入脚本到UserData(适合短脚本)
如果你的Python脚本比较短,也可以不用S3,直接把脚本编码后嵌入到CFN里:
1. 在deploy.sh里编码脚本并传入CFN参数
# 把Python脚本转成Base64编码(-w 0避免换行) PYTHON_SCRIPT=$(base64 -w 0 your-python-server-script.py) # 创建堆栈时传入这个参数 aws cloudformation create-stack \ --stack-name your-stack-name \ --template-body file://your-cfn-template.yml \ --parameters \ ParameterKey=InstanceType,ParameterValue=t2.micro \ ParameterKey=PythonScript,ParameterValue="$PYTHON_SCRIPT" \ # 其他参数(如KeyName、LatestAmiId等)...
2. 在CFN模板里定义参数并解码写入文件
# 先添加参数定义 Parameters: # 你的其他现有参数... PythonScript: Type: String Description: Base64 encoded content of the Python server script # 修改EC2实例的UserData EC2Instance2: Type: AWS::EC2::Instance Properties: # 其他属性不变... UserData: Fn::Base64: !Sub | #!/bin/bash sleep 20 sudo apt-get update -y sudo apt-get install python3-pip python3-flask -y # 解码Base64内容并写入脚本文件 echo "${PythonScript}" | base64 -d > /home/ubuntu/your-python-server-script.py sudo chmod +x /home/ubuntu/your-python-server-script.py nohup python3 /home/ubuntu/your-python-server-script.py > /home/ubuntu/server.log 2>&1 &
调试小技巧
如果UserData执行失败,登录实例查看这两个日志文件排查问题:
/var/log/cloud-init.log:cloud-init工具的详细执行日志/var/log/cloud-init-output.log:你的初始化脚本的输出内容,能看到具体的错误信息
内容的提问来源于stack exchange,提问作者ShaiB
相关产品推荐
相关产品推荐

