You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从AWS React应用触发EC2的Ansible Playbook遇阻,求SSM文档配置帮助

解决方案:在AWS生态内通过React触发EC2上的Ansible Playbook

嗨,我来帮你理清在AWS生态里实现这个需求的正确路径,先从你当前的SSM Document问题说起哈!

1. 先修正你的SSM Document

你的EC2实例看起来是Linux系统(路径用的是/echo_configure/Config),但你用了aws:runPowerShellScript——这是给Windows实例用的!另外,SSM的每个mainSteps是独立的执行会话,第一个步骤里的cd不会影响第二个步骤的工作目录,所以第二个步骤根本找不到你的playbook。

修正后的SSM Document应该用aws:runShellScript,并且用绝对路径直接执行playbook(或者把命令合并成一行):

{
  "schemaVersion": "2.2",
  "description": "Execute Ansible Playbook for device configuration",
  "parameters": {
    "PlaybookFullPath": {
      "type": "String",
      "description": "Absolute path to your Ansible playbook",
      "default": "/echo_configure/Config/apply.yml"
    }
  },
  "mainSteps": [
    {
      "action": "aws:runShellScript",
      "name": "runAnsiblePlaybook",
      "inputs": {
        "runCommand": [
          "ansible-playbook {{ PlaybookFullPath }}"
        ]
      }
    }
  ]
}

为什么这么改?

  • aws:runShellScript是Linux实例的正确动作类型
  • 用绝对路径调用playbook,避免了切换目录的问题,更可靠
  • 增加了参数PlaybookFullPath,以后如果换playbook路径不用改Document

2. 整体实现流程(AWS生态内)

要从React应用触发这个SSM命令,绝对不能直接在前端调用AWS SSM API(会暴露你的AWS凭证,非常不安全),正确的架构是:

React按钮 → API Gateway → Lambda函数 → SSM SendCommand → EC2执行Ansible Playbook

步骤分解:

(1) 确保EC2实例满足SSM管理条件

  • 实例已经安装并运行SSM Agent:Linux实例默认自带,Windows需要手动安装
  • 实例关联了IAM角色,包含AmazonSSMManagedInstanceCore权限策略(让SSM能管理这个实例)
  • 手动测试在EC2上运行ansible-playbook /echo_configure/Config/apply.yml,确保playbook本身能正常执行

(2) 创建Lambda函数作为中间层

Lambda需要有调用SSMSendCommand的权限,所以给Lambda的IAM角色添加如下权限策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ssm:SendCommand",
      "Resource": [
        "arn:aws:ssm:你的区域:你的账号:document/你的SSM Document名称",
        "arn:aws:ec2:你的区域:你的账号:instance/目标EC2实例ID"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "ssm:GetCommandInvocation",
      "Resource": "*"
    }
  ]
}

Lambda的代码示例(用Node.js):

const { SSMClient, SendCommandCommand } = require("@aws-sdk/client-ssm");

const client = new SSMClient({ region: "你的AWS区域" });

exports.handler = async (event) => {
  const params = {
    DocumentName: "你的SSM Document名称",
    InstanceIds: ["目标EC2实例ID"], // 或者用Targets按标签筛选实例
    Parameters: {
      PlaybookFullPath: ["/echo_configure/Config/apply.yml"]
    }
  };

  try {
    const command = new SendCommandCommand(params);
    const response = await client.send(command);
    return {
      statusCode: 200,
      body: JSON.stringify({
        commandId: response.Command.CommandId,
        message: "Command sent successfully"
      })
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message })
    };
  }
};

(3) 配置API Gateway

  • 创建一个REST API,添加POST方法,集成到刚才的Lambda函数
  • 启用CORS,允许你的React应用域名访问这个API

(4) React应用触发命令

在React的按钮点击事件里,调用API Gateway的接口:

const triggerPlaybook = async () => {
  try {
    const response = await fetch("你的API Gateway URL", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({}) // 如果需要传参数给playbook,可以在这里添加
    });
    const data = await response.json();
    console.log("Command sent:", data);
    // 可以进一步轮询获取命令执行状态
  } catch (error) {
    console.error("Error triggering playbook:", error);
  }
};

3. 进阶优化

  • 获取执行状态:可以在Lambda里添加GetCommandInvocation的调用,或者前端轮询另一个Lambda接口,获取命令的执行结果(成功/失败/输出日志)
  • 动态传递参数:如果需要给Ansible Playbook传设备信息,可以在SSM Document里增加参数,Lambda从API Gateway获取参数后传递给SSM,Playbook通过extra_vars接收
  • 实例筛选:如果有多个EC2实例,可以用Targets参数按标签筛选,比如[{Key: "tag:DeviceType", Values: ["你的设备类型"]}]

内容的提问来源于stack exchange,提问作者IAmTazlan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:20:31