aws:executeScript - 运行脚本 - AWS Systems Manager

aws:executeScript - 运行脚本

使用指定的运行时和处理程序提供的 Python 或 PowerShell 脚本。每个 aws:executeScript 操作最多可以运行 600 秒(10 分钟)时间。您可以通过指定 aws:executeScript 步骤的 timeoutSeconds 参数来限制超时。

在函数中使用 return 语句将输出添加到输出有效负载中。有关为您的 aws:executeScript 操作定义输出的示例,请参阅示例 2:脚本化运行手册。您还可以将运行手册中 aws:executeScript 操作的输出发送到您指定的 Amazon CloudWatch Logs 日志组。有关更多信息,请参阅 使用 CloudWatch Logs 记录自动化操作输出

如果想要将 aws:executeScript 操作的输出发送到 CloudWatch Logs,或者如果您为 aws:executeScript 操作指定的脚本调用 AWS API 操作,则始终需要 AWS Identity and Access Management (IAM) 服务角色(或承担角色)运行运行手册。

aws:executeScript 操作包含以下预安装的 PowerShell 核心模块。

  • Microsoft.PowerShell.Host

  • Microsoft.PowerShell.Management

  • Microsoft.PowerShell.Security

  • Microsoft.PowerShell.Utility

  • PackageManagement

  • PowerShellGet

要使用未预装的 PowerShell 核心模块,脚本必须安装带有 -Force 标志的模块,如以下命令所示。不支持 AWSPowerShell.NetCore 模块。用您想要安装的模块替换 ModuleName

Install-Module ModuleName -Force

要在脚本中使用 PowerShell 核心 cmdlet,我们建议您使用 AWS.Tools 模块,如以下命令所示。将每个示例资源占位符替换为您自己的信息。

  • Amazon S3 cmdlet。

    Install-Module AWS.Tools.S3 -Force Get-S3Bucket -BucketName amzn-s3-demo-bucket
  • Amazon EC2 cmdlet

    Install-Module AWS.Tools.EC2 -Force Get-EC2InstanceStatus -InstanceId instance-id
  • 通用或独立于服务的 AWS Tools for Windows PowerShell cmdlet。

    Install-Module AWS.Tools.Common -Force Get-AWSRegion

如果脚本除了使用 PowerShell 核心 cmdlet 之外还初始化新对象,则还必须导入模块,如以下命令所示。

Install-Module AWS.Tools.EC2 -Force Import-Module AWS.Tools.EC2 $tag = New-Object Amazon.EC2.Model.Tag $tag.Key = "Tag" $tag.Value = "TagValue" New-EC2Tag -Resource i-02573cafcfEXAMPLE -Tag $tag

有关安装和导入 AWS.Tools 模块以及在运行手册中使用 PowerShell 核心 cmdlet 的示例,请参阅 自动化运行手册的视觉对象设计体验

输入

提供运行脚本所需的信息。将每个示例资源占位符替换为您自己的信息。

注意

Python 脚本的附件可以是 .py 文件或包含该脚本的 .zip 文件。PowerShell 脚本必须存储在 .zip 文件中。

YAML
action: "aws:executeScript" inputs: Runtime: runtime Handler: "functionName" InputPayload: scriptInput: '{{parameterValue}}' Script: |- def functionName(events, context): ... Attachment: "scriptAttachment.zip"
JSON
{ "action": "aws:executeScript", "inputs": { "Runtime": "runtime", "Handler": "functionName", "InputPayload": { "scriptInput": "{{parameterValue}}" }, "Attachment": "scriptAttachment.zip" } }
运行时

用于运行提供的脚本的运行时语言。aws:executeScript 支持 Python 3.7 (python3.7)、Python 3.8 (python3.8)、Python 3.9 (python3.9)Python 3.10 (python3.10)、Python 3.11 (python3.11) PowerShell Core 6.0 (dotnetcore2.1)、PowerShell 7.0 (dotnetcore3.1) 脚本和 PowerShell 7.4 (dotnet8) 脚本。

支持的值:python3.7 | python3.8 | python3.9 | python3.10 | python3.11 | PowerShell Core 6.0 | PowerShell 7.0 | PowerShell 7.4

类型:字符串

必需:是

注意

对于 python 运行时系统,环境提供 512 MB 的内存和 512 MB 的磁盘空间。对于 PowerShell 运行时,环境会提供 1024 MB 的内存和 512 MB 的磁盘空间。

处理程序

函数的名称。您必须确保在处理程序中定义的函数具有两个参数:eventscontext。PowerShell 运行时不支持此参数。

类型:字符串

必需:是(Python)| 不支持(PowerShell)

InputPayload

将传递给处理程序的第一个参数的 JSON 或 YAML 对象。这可用于将输入数据传递给脚本。

类型:字符串

必需:否

Python
description: Tag an instance schemaVersion: '0.3' assumeRole: '{{AutomationAssumeRole}}' parameters: AutomationAssumeRole: type: String description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.' InstanceId: type: String description: (Required) The ID of the EC2 instance you want to tag. mainSteps: - name: tagInstance action: 'aws:executeScript' inputs: Runtime: "python3.11" Handler: tagInstance InputPayload: instanceId: '{{InstanceId}}' Script: |- def tagInstance(events,context): import boto3 #Initialize client ec2 = boto3.client('ec2') instanceId = events['instanceId'] tag = { "Key": "Env", "Value": "ExamplePython" } print(f"Adding tag {tag} to instance id {instanceId}") ec2.create_tags( Resources=[instanceId], Tags=[tag] ) return tag outputs: - Type: String Name: TagKey Selector: $.Payload.Key outputs: - tagInstance.TagKey
PowerShell
description: Tag an instance schemaVersion: '0.3' assumeRole: '{{AutomationAssumeRole}}' parameters: AutomationAssumeRole: type: String description: (Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook. InstanceId: type: String description: (Required) The ID of the EC2 instance you want to tag. mainSteps: - name: tagInstance action: aws:executeScript isEnd: true inputs: Runtime: PowerShell 7.0 InputPayload: instanceId: '{{InstanceId}}' Script: |- Install-Module AWS.Tools.EC2 -Force Import-Module AWS.Tools.EC2 $input = $env:InputPayload | ConvertFrom-Json $tag = New-Object Amazon.EC2.Model.Tag $tag.Key = "Env" $tag.Value = "ExamplePowerShell" Write-Information "Adding tag key: $($tag.Key) and value: $($tag.Value) to instance id $($input.instanceId)" New-EC2Tag -Resource $input.instanceId -Tag $tag return $tag outputs: - Type: String Name: TagKey Selector: $.Payload.Key outputs: - tagInstance.TagKey
Script

要在自动化期间运行的嵌入式脚本。

类型:字符串

必需:否 (Python) | 是 (PowerShell)

附件

可以由操作调用的单独脚本文件或 .zip 文件的名称。指定与您在 Attachments 请求参数中指定的文档附件文件的 Name 相同的值。有关更多信息,请参阅 AWS Systems Manager API 参考中的附件。如果您使用附件提供脚本,还必须在您的运行手册的顶级元素部分中定义一个 files 部分。有关更多信息,请参阅 架构版本 0.3

要为 Python 调用文件,请在 Handler 中使用 filename.method_name 格式。

注意

Python 脚本的附件可以是 .py 文件或包含该脚本的 .zip 文件。PowerShell 脚本必须存储在 .zip 文件中。

当在附件中包含 Python 库时,我们建议在每个模块目录中添加一个空__init__.py 文件。这允许您从脚本内容的附件中的库导入模块。例如:from library import module

类型:字符串

必需:否

输出
有效负载

函数返回的对象的 JSON 表示形式。返回最多 100KB 的数据。如果输出列表,则最多返回 100 个项目。

通过 aws:executeScript 使用附件

附件提供了一种强大的方法,可以将复杂的脚本、多个模块和外部依赖项打包并重复用于 aws:executeScript 操作。在您需要执行以下操作时,请使用附件:

  • 将多个 Python 模块或 PowerShell 脚本打包在一起。

  • 在多个运行手册中重复使用相同的脚本逻辑。

  • 在脚本中包含外部库或依赖项。

  • 通过分离复杂的脚本逻辑,保持运行手册定义简洁。

  • 在团队或自动化工作流之间共享脚本包。

附件结构和打包

您可以附加单个文件或包含多个文件的 zip 包。具体结构取决于使用案例:

单个文件附件

对于简单的脚本,您可以附加单个 .py 文件 (Python) 或包含单个 PowerShell 脚本的 .zip 文件。

多模块包

对于需要多个模块的复杂自动化,请创建具有以下建议结构的 zip 包:

my-automation-package.zip ├── main.py # Entry point script ├── utils/ │ ├── __init__.py # Required for Python module imports │ ├── helper_functions.py # Utility functions │ └── aws_operations.py # AWS-specific operations ├── config/ │ ├── __init__.py │ └── settings.py # Configuration settings └── requirements.txt # Optional: document dependencies
重要

对于 Python 包,您必须在每个包含 Python 模块的目录中包含一个空的 __init__.py 文件。这样您就可以使用标准的 Python 导入语法(例如 from utils import helper_functions)来导入模块。

PowerShell 包结构

PowerShell 附件必须打包为 zip 文件,其结构如下:

my-powershell-package.zip ├── Main.ps1 # Entry point script ├── Modules/ │ ├── HelperFunctions.ps1 # Utility functions │ └── AWSOperations.ps1 # AWS-specific operations └── Config/ └── Settings.ps1 # Configuration settings

创建带附件的运行手册

请按照以下步骤创建带附件的运行手册:

  1. 将附件上传到 Amazon S3

    将脚本文件或 zip 包上传到自动化角色可访问的 S3 存储桶。请记下 S3 URI,以便在下一步中使用。

    aws s3 cp my-automation-package.zip s3://my-automation-bucket/scripts/
  2. 计算附件校验和

    计算附件文件的 SHA-256 校验和以进行安全验证:

    # Linux/macOS shasum -a 256 my-automation-package.zip # Windows PowerShell Get-FileHash -Algorithm SHA256 my-automation-package.zip
  3. 在运行手册中定义 files 部分

    在运行手册的顶层添加 files 部分以引用附件:

    files: my-automation-package.zip: sourceType: "S3" sourceInfo: path: "s3://my-automation-bucket/scripts/my-automation-package.zip" checksums: sha256: "your-calculated-checksum-here"
  4. 在 executeScript 步骤中引用附件

    使用 Attachment 参数来引用上传的文件:

    - name: runMyScript action: aws:executeScript inputs: Runtime: python3.11 Handler: main.process_data Attachment: my-automation-package.zip InputPayload: inputData: "{{InputParameter}}"

aws:executeScript 附件示例

以下示例演示了使用附件和 aws:executeScript 操作的不同方法。

示例 1:单个文件附件

此示例展示如何使用单个 Python 文件作为附件来处理 EC2 实例数据。

附件文件:process_instance.py

创建一个包含以下内容的 Python 文件:

import boto3 import json def process_instance_data(events, context): """Process EC2 instance data and return formatted results.""" try: instance_id = events.get('instanceId') if not instance_id: raise ValueError("instanceId is required") ec2 = boto3.client('ec2') # Get instance details response = ec2.describe_instances(InstanceIds=[instance_id]) instance = response['Reservations'][0]['Instances'][0] # Format the response result = { 'instanceId': instance_id, 'instanceType': instance['InstanceType'], 'state': instance['State']['Name'], 'availabilityZone': instance['Placement']['AvailabilityZone'], 'tags': {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])} } print(f"Successfully processed instance {instance_id}") return result except Exception as e: print(f"Error processing instance: {str(e)}") raise
完整运行手册

以下是使用单个文件附件的完整运行手册:

description: Process EC2 instance data using single file attachment schemaVersion: '0.3' assumeRole: '{{AutomationAssumeRole}}' parameters: AutomationAssumeRole: type: String description: (Required) IAM role for automation execution InstanceId: type: String description: (Required) EC2 instance ID to process files: process_instance.py: sourceType: "S3" sourceInfo: path: "s3://my-automation-bucket/scripts/process_instance.py" checksums: sha256: "abc123def456..." mainSteps: - name: processInstance action: aws:executeScript inputs: Runtime: python3.11 Handler: process_instance.process_instance_data Attachment: process_instance.py InputPayload: instanceId: '{{InstanceId}}' outputs: - Type: StringMap Name: InstanceData Selector: $.Payload outputs: - processInstance.InstanceData

示例 2:多模块包

此示例演示如何使用包含多个 Python 模块的 zip 包进行复杂的 S3 存储桶操作。

包结构

创建具有以下结构的 zip 包:

s3-operations.zip ├── main.py ├── utils/ │ ├── __init__.py │ ├── s3_helper.py │ └── validation.py └── config/ ├── __init__.py └── settings.py
main.py(入口点)

编排操作的主脚本:

from utils.s3_helper import S3Operations from utils.validation import validate_bucket_name from config.settings import get_default_settings def cleanup_s3_bucket(events, context): """Clean up S3 bucket based on specified criteria.""" try: bucket_name = events.get('bucketName') max_age_days = events.get('maxAgeDays', 30) # Validate inputs if not validate_bucket_name(bucket_name): raise ValueError(f"Invalid bucket name: {bucket_name}") # Initialize S3 operations s3_ops = S3Operations() settings = get_default_settings() # Perform cleanup deleted_objects = s3_ops.delete_old_objects( bucket_name, max_age_days, settings['dry_run'] ) result = { 'bucketName': bucket_name, 'deletedCount': len(deleted_objects), 'deletedObjects': deleted_objects[:10], # Return first 10 for brevity 'dryRun': settings['dry_run'] } print(f"Cleanup completed for bucket {bucket_name}") return result except Exception as e: print(f"Error during S3 cleanup: {str(e)}") raise

aws:executeScript 附件故障排除

使用以下指导来解决 aws:executeScript 附件的常见问题:

模块导入错误

如果在使用多模块包时收到导入错误:

  • 确保在包含 Python 模块的每个目录中都包含一个空的 __init__.py 文件。

  • 验证导入语句是否与 zip 包中的实际文件和目录结构相匹配。

  • 始终使用相对导入(例如 from .utils import helper)或绝对导入(例如 from utils import helper)。

未找到附件错误

如果自动化未能找到附件:

  • 验证 Attachment 参数值是否与 files 部分中的键完全匹配。

  • files 部分中检查 S3 存储桶路径和文件名是否正确。

  • 确保自动化角色对附件 S3 位置具有 s3:GetObject 权限。

  • 验证运行手册中的校验和是否与实际文件校验和匹配。

处理程序函数错误

如果收到与处理程序相关的错误:

  • 对于 Python:在 Handler 参数中使用格式 filename.function_name(例如 main.process_data)。

  • 确保处理程序函数只接受两个参数:eventscontext

  • 对于 PowerShell:请勿指定 Handler 参数;脚本将直接运行。

脚本执行失败

如果脚本在执行过程中失败:

  • 检查自动化执行历史记录,获取详细的错误消息和堆栈跟踪。

  • 使用 print() 语句 (Python) 或 Write-Information (PowerShell) 添加调试输出。

  • 验证自动化角色是否已被授予所有必需的 AWS 权限。

  • 在将脚本逻辑打包为附件之前,请在本地测试脚本逻辑。

退出代码和错误处理

要正确处理错误并返回退出代码:

  • 在 Python 中:使用 raise Exception("error message") 指示脚本失败。

  • 在 PowerShell 中:使用 throw "error message"Write-Error 指示失败。

  • 从函数返回结构化数据以提供详细的成功/失败信息。

  • 使用 try-catch 块优雅地处理异常并提供有意义的错误消息。