amazon-web-servicesaws-cloudformationamazon-cloudwatchamazon-ebsamazon-cloudwatch-events

Create Cloudwatch Event for EBS Snapshot using Cloudformation


I am trying to create cloudwatch scheduled event for taking snapshot of my ebs. I am new to cloudformation not much familiar with it that's why having complexity in achieving this. I am attaching my current template which spawns my ec2 instance and override the default volume from 10gb to 20gb. I want to create a cloudwatch event on exactly the same created volume to take the snapshot of this volume that has been created from this template. I would be glad if anyone can help me in setting an event with target using the cloudformation syntax.

Parameters:
  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: 'AWS::EC2::KeyPair::KeyName'
Resources:
  Ec2Instance:
    Type: 'AWS::EC2::Instance'
    DependsOn:
      - InstanceSecurityGroup
      - CWIAMRole
      - EC2CWInstanceProfile
    Properties:
      KeyName: !Ref KeyName
      ImageId: ami-057a963e8be173b19
      InstanceType: t3a.micro
      IamInstanceProfile: !Ref EC2CWInstanceProfile
      NetworkInterfaces:
        - AssociatePublicIpAddress: 'True'
          DeleteOnTermination: 'True'
          DeviceIndex: '0'
          # Add subnet id below
          SubnetId: subnet-031c6fb8172d780aa
          GroupSet:
            - !Ref InstanceSecurityGroup
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeType: gp2
            DeleteOnTermination: 'true'
            VolumeSize: '20'
  LambdaSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable SSH access via port 22
      # Add you vpc id below
      VpcId: vpc-02e91d5d082e3a097
      GroupName: DS Lambda Security Group
  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    DependsOn:
      - LambdaSecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      # Add you vpc id below
      VpcId: vpc-02e91d5d082e3a097
      GroupName: DS DB Instance Security Group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          # Add vpn ip below for e.g 192.168.78.2/32
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '5432'
          ToPort: '5432'
          SourceSecurityGroupId: !Ref LambdaSecurityGroup
  CWIAMRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/CloudWatchAgentAdminPolicy'
      RoleName: DS_CW_AGENT_ROLE
  EC2CWInstanceProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      InstanceProfileName: EC2CWInstanceProfile
      Roles:
        - !Ref CWIAMRole
  S3VPCEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      RouteTableIds:
        - 'rtb-031f3057458433643'
      ServiceName: com.amazonaws.ap-southeast-1.s3
      VpcId: vpc-02e91d5d082e3a097

Solution

  • Sadly, you can't do this easily. The reason is that the Instance resource does not return the id of its root volume.

    What's more, you can't create an independent AWS::EC2::Volume resource and use it as a root volume in your instance. This is only for additional volumes.

    The only way to get the volume id of your root device would be through development of a custom resource. This would be in the form of lambda function, which would take the instance id, and use AWS SDK to find the volume id and return to cloud formation. With that volume id you could create CloudWatch Event rules.