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

Windows EC2 User Data脚本无法正常挂载EBS卷问题排查

问题描述

通过CloudFormation(YAML)启动新EC2实例时,使用UserData脚本将EBS卷vol-0e5a92637c3dec929x从旧实例i-05e13cbyrr78f75f7分离并挂载到新实例。脚本中加入了timeout命令等待卷分离完成,但实例启动时脚本无法正常挂载卷;手动运行相同脚本却能正常工作。

原UserData脚本

UserData: !Base64
        <script>
        aws ec2 detach-volume --instance-id i-05e13cbyrr78f75f7 --volume-id vol-0e5a92637c3dec929x --region us-east-1
        timeout /t 100
        for /F %%L in ('powershell Invoke-RestMethod -Uri 'http://169.254.169.254/latest/meta-data/instance-id'') do (set "ID=%%L")
        aws ec2 attach-volume --volume-id vol-0e5a92637c3dec929x --instance-id %ID% --device xvdf --region us-east-1
        </script>

UserDataExecution.log日志内容

2023/04/28 07:05:43Z: <script> tag was provided.. running script content
2023/04/28 07:06:14Z: Message: The errors from user data script: usage: 
Note: AWS CLI version 2, the latest major version of the AWS CLI, is now stable and recommended for general use. For more information, see the AWS CLI version 2 installation instructions at: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument --instance-id: expected one argument

2023/04/28 07:06:14Z: Message: The output from user data script: 
C:\Windows\system32&gt;aws ec2 detach-volume --instance-id i-05e13cbyrr78f75f7 --volume-id vol-0e5a92637c3dec929x --region us-east-1 timeout /t 100 for /F %L in ('powershell Invoke-RestMethod -Uri 'http://169.254.169.254/latest/meta-data/instance-id'') do (set "ID=%L") aws ec2 attach-volume --volume-id vol-0e5a92637c3dec929x --instance-id  --device xvdf --region us-east-1  

2023/04/28 07:06:14Z: User data script completed.
问题原因与解决办法

核心问题分析

  1. YAML多行格式错误:原脚本在CloudFormation的YAML中未正确处理多行内容,导致所有命令被合并为一行执行。AWS CLI将后续的timeout、for循环等参数当成detach-volume的额外参数,直接引发参数错误。
  2. CMD变量延迟扩展未启用:CMD默认会预解析整个脚本的变量,for循环中设置的%ID%在脚本执行时还未被赋值,导致attach-volume命令中--instance-id后面为空值,触发错误。
  3. 固定超时不可靠:timeout /t 100是固定等待时间,无法确保EBS卷真正完成分离,可能出现卷仍处于使用状态的情况。

修正后的UserData脚本

UserData: !Base64 |
        <script>
        @echo off
        rem 启用CMD延迟扩展,确保变量实时更新
        setlocal enabledelayedexpansion
        
        rem 分离EBS卷
        aws ec2 detach-volume --instance-id i-05e13cbyrr78f75f7 --volume-id vol-0e5a92637c3dec929x --region us-east-1
        
        rem 等待卷变为可用状态(替代固定超时,更可靠)
        aws ec2 wait volume-available --volume-ids vol-0e5a92637c3dec929x --region us-east-1
        
        rem 获取当前实例ID
        for /F %%L in ('powershell Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/instance-id"') do (set "ID=%%L")
        
        rem 挂载EBS卷,使用!ID!调用延迟扩展变量
        aws ec2 attach-volume --volume-id vol-0e5a92637c3dec929x --instance-id !ID! --device xvdf --region us-east-1
        </script>

关键修正点说明

  • YAML多行处理:使用|符号确保脚本内容保留原始换行,避免命令合并。
  • 启用延迟扩展:通过setlocal enabledelayedexpansion启用CMD的延迟扩展,变量引用改为!ID!,确保for循环赋值后变量能被正确读取。
  • 替换固定超时:用aws ec2 wait volume-available命令轮询卷状态,直到卷变为可用再执行挂载,避免因固定等待时间不足导致的挂载失败。
  • 引号转义:将PowerShell命令中的单引号改为双引号,避免CMD解析冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:53:09