'Create AMI of a given EC2 from cloud formation

I have to create an AMI of a given EC2 istance from cloud formation, ad after create an ec2 from this AMI. How to do this? My principal problem is the first part



Solution 1:[1]

The below code is a function that can be called from as a CustomResource to create an AMI.

I haven't used it in a long time but it should still work.

Your CustomResource will need to pass in the Region and Instance (and Tags if you want those).

In order to create a new EC2 instance from this you would need to use the return value of ImageId and input that as the AMI to a AWS::EC2::Instance.

var Aws = require("aws-sdk");
var Response = require('cfn-response');

exports.handler = function (e, c) {

    console.log("REQUEST RECEIVED:\n" + JSON.stringify(e));

    // For Delete requests, immediately send a SUCCESS response.
    if (e.RequestType === "Delete") {
        Response.send(e, c, Response.SUCCESS);
        return;
    }

    console.log("Region=" + e.ResourceProperties.Region);
    console.log("Instance=" + e.ResourceProperties.Instance);

    var ec2 = new Aws.EC2({ region: e.ResourceProperties.Region });
    console.log("ec2=" + ec2);
    console.log("Tags=" + e.ResourceProperties.Tags);

    var params = {
        InstanceId: e.ResourceProperties.Instance,
        Name: e.ResourceProperties.AmiName
    };

    console.log("params=" + params);
    console.log("params.InstanceIds=" + params.InstanceIds);

    var responseStatus = "FAILED";

    ec2.createImage(params, function (err, data) {
        if (err) {
            console.log("createImage.err:" + err.toString(), err.stack.toString());
            Response.send(e, c, Response.FAILED);
        } // an error occurred
        else {
            console.log("createImage" + data);
            responseStatus = "SUCCESS";

            var responseData = {};
            responseData["ImageId"] = data.ImageId;

            var tagParams = {
                Resources: [data.ImageId],
                Tags: e.ResourceProperties.Tags
            }

            ec2.createTags(tagParams, function (err, data) {
                if (err) {
                    data = { Error: "DescribeImages call failed" };
                    console.log(data.Error + ":\n", err);
                    Response.send(e, c, Response.FAILED);
                } else {
                    console.log(data);
                    Response.send(e, c, Response.SUCCESS, responseData);
                }
            });
        }
    });
};

Solution 2:[2]

You cannot do this.

AWS CloudFormation is designed to deploy infrastructure in a repeatable manner. It is used to create new infrastructure. It cannot be used to modify existing infrastructure.

You would need to create the AMI of the Amazon EC2 instance outside of CloudFormation. You can then use CloudFormation to launch a new Amazon EC2 instance using this AMI.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tim Bassett
Solution 2 John Rotenstein