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
-
You can do it via Terraform apparently : https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ami_from_instance – Devang Sanghani Mar 09 '22 at 09:35
2 Answers
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);
}
});
}
});
};

- 1,325
- 1
- 12
- 23
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.

- 241,921
- 22
- 380
- 470
-
1
-
Yes, but (shh!) I didn't want to raise that. The fact is, we can do _anything_ with a custom resource, but I would not consider this "clone an instance" requirement as an appropriate activity to do with CloudFormation (not to mention that it is reasonably complex to write a Custom Resource). Each to their own! – John Rotenstein Mar 09 '22 at 11:38
-
@JohnRotenstein - SO encouraged me to write a comment as to why I downvoted this answer: There is nothing about what OP is asking that is not a repeatable manner. And just because something is complex, you shouldn't discourage others from attempting it. If the OP has a need, it is not up to you to deem it inappropriate. – Tim Bassett Mar 09 '22 at 18:38
-
That's cool. @TimBassett I encourage you to add an answer that includes Custom Resources. – John Rotenstein Mar 09 '22 at 21:43