如何在CloudFormation中基于快照创建根卷并挂载到EC2实例
基于现有快照创建卷并挂载到EC2实例的CloudFormation实现
当然可以在CloudFormation模板中基于快照创建存储卷并挂载到EC2实例,你遇到的错误是因为**/dev/sda1是实例的根设备(系统盘)**,实例启动时已经通过BlockDeviceMappings配置了该设备,无法重复挂载。下面提供两种可行的解决方案:
方案一:直接用快照作为实例的根卷
如果你想让实例启动时直接使用快照创建的卷作为系统盘,不需要额外的VolumeAttachment,直接修改EC2实例的BlockDeviceMappings配置即可:
Resources: EC2Example: Type: "AWS::EC2::Instance" Metadata: AWS::CloudFormation::Init: services: sysvint: codedeploy-agent: enabled: 'true' ensureRunning: 'true' Properties: ImageId: !Ref ImageId InstanceType: !Ref InstanceType KeyName: !Ref SSHKeyName IamInstanceProfile: "EC2CodeDeploy" NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" GroupSet: - Ref: "SecurityGroupIds" SubnetId: Ref: "PrivateSubnet" BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeType: io1 Iops: !Ref IOPS DeleteOnTermination: false SnapshotId: 'MySnapshotID' # 新增:指定快照ID # 可选:如果快照容量不够,可指定更大的VolumeSize,需大于等于快照大小 # VolumeSize: !Ref VolumeSize
方案二:挂载为额外的数据卷
如果你想保留原根卷,把快照创建的卷作为额外的数据卷挂载,需要选择一个未被占用的设备名(比如/dev/sdf,不同操作系统可能会映射为/dev/xvdf或/dev/nvme1n1),并通过VolumeAttachment关联实例:
完整模板片段
Resources: EC2Example: Type: "AWS::EC2::Instance" Metadata: AWS::CloudFormation::Init: services: sysvint: codedeploy-agent: enabled: 'true' ensureRunning: 'true' files: "/etc/fstab": content: | /dev/xvdf /data ext4 defaults,nofail 0 2 mode: "000644" commands: 01_mount_volume: command: "mkdir -p /data && mount /data" Properties: ImageId: !Ref ImageId InstanceType: !Ref InstanceType KeyName: !Ref SSHKeyName IamInstanceProfile: "EC2CodeDeploy" NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" GroupSet: - Ref: "SecurityGroupIds" SubnetId: Ref: "PrivateSubnet" BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeType: io1 Iops: !Ref IOPS DeleteOnTermination: false VolumeSize: !Ref VolumeSize UserData: Fn::Base64: !Sub | #!/bin/bash /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Example --region ${AWS::Region} NewVolume: Type: AWS::EC2::Volume Properties: AvailabilityZone: !GetAtt EC2Example.AvailabilityZone # 确保和实例同可用区 SnapshotId: 'MySnapshotID' VolumeType: io1 # 可选:按需调整卷类型 Iops: !Ref IOPS Tags: - Key: MISPVol Value: MISPVol MountPoint: Type: AWS::EC2::VolumeAttachment Properties: InstanceId: !Ref EC2Example VolumeId: !Ref NewVolume Device: /dev/sdf # 使用未被占用的设备名 DependsOn: EC2Example # 确保实例创建完成后再挂载
注意事项
- 卷和实例必须处于同一个可用区(AZ),上面用
!GetAtt EC2Example.AvailabilityZone自动匹配,避免手动配置出错。 - 不同操作系统的设备名映射可能不同:比如Amazon Linux 2会把
/dev/sdf识别为/dev/xvdf,Ubuntu可能识别为/dev/nvme1n1,需要根据系统调整fstab和挂载命令中的路径。 cfn-init和UserData用于在实例启动后自动创建挂载目录并配置开机挂载,确保重启后卷依然可用。
内容的提问来源于stack exchange,提问作者hf8w34fg4wpg
相关产品推荐
相关产品推荐

