- Newest
- Most votes
- Most comments
SOLVED by using IPv6 to call a Lambda HTTP Endpoint from EC2 Userdata which in turn calls cfn-signal on behalf of the EC2.
cfn-signal doesn't need to be called from the subject instance, as long as it has the correct paramaters.
Lambda code:
Type: AWS::Lambda::Function
Properties:
FunctionName: !Sub "${EnvironmentName}-MyCfnSignalLambda"
Handler: index.handler
Runtime: nodejs22.x
Code:
ZipFile: |
const { EC2Client, DescribeInstancesCommand } = require("@aws-sdk/client-ec2");
const { CloudFormationClient, SignalResourceCommand } = require("@aws-sdk/client-cloudformation");
exports.handler = async (event) => {
console.log(`Received event: ${JSON.stringify(event)}`);
const region = process.env.AWS_REGION;
const ec2Client = new EC2Client({ region });
const cloudFormationClient = new CloudFormationClient({ region });
try {
const { LogicalResourceId, Status } = JSON.parse(event.body);
const stackName = process.env.AWS_STACK_NAME;
const environmentName = process.env.ENVIRONMENT_NAME;
console.log(`Searching for EC2 instance in stack ${stackName}`);
const describeInstancesCommand = new DescribeInstancesCommand({
Filters: [
{ Name: "tag:aws:cloudformation:stack-name", Values: [stackName] },
{ Name: "instance-state-name", Values: ["pending", "running"] },
],
});
const describeInstancesResponse = await ec2Client.send(describeInstancesCommand);
if (!describeInstancesResponse.Reservations || describeInstancesResponse.Reservations.length === 0 || !describeInstancesResponse.Reservations[0].Instances || describeInstancesResponse.Reservations[0].Instances.length === 0) {
throw new Error(`Could not find EC2 instance in stack ${stackName}`);
}
const instanceId = describeInstancesResponse.Reservations[0].Instances[0].InstanceId;
console.log(`Found EC2 instance ID: ${instanceId}`);
console.log(`Signaling resource ${LogicalResourceId} in stack ${stackName} with status ${Status} for instance ${instanceId}`);
const signalResourceCommand = new SignalResourceCommand({
StackName: stackName,
LogicalResourceId: LogicalResourceId,
UniqueId: instanceId,
Status: Status,
});
await cloudFormationClient.send(signalResourceCommand);
console.log("Signal sent successfully.");
return {
statusCode: 200,
body: JSON.stringify(`Signal sent successfully for instance ${instanceId}`),
};
} catch (error) {
console.error(`Error signaling resource: ${error}`);
throw error;
}
};
UserData:
SIGNAL_PAYLOAD='{ "LogicalResourceId": "MyEc2Instance", "Status": "SUCCESS" }'
LAMBDA_FUNCTION_URL="${LambdaFunctionUrl}"
curl -6 -X POST -H "Content-Type: application/json" \
-d "$SIGNAL_PAYLOAD" \
"$LAMBDA_FUNCTION_URL"
answered 10 months ago
When trying to eliminate public IPv4 addresses to reduce costs, you're correct that there are challenges with services like cf-signal that require IPv4 connectivity.
For IPv6-only instances that need to communicate with IPv4-only AWS services (like CloudFormation for cf-signal), there are a few approaches:
- NAT64 with DNS64: This is AWS's solution for enabling IPv6-only resources to communicate with IPv4 services. You would:
- Create a NAT gateway
- In the VPC routing table for your instance's subnet, create a route for traffic to '64:ff9b::/96' that forwards to the NAT gateway
- Enable DNS64 for the subnet
-
NAT Gateway: For instances with private IPv4 addresses, a NAT gateway allows outbound connectivity to IPv4 services.
-
VPC Endpoints: For some AWS services, you might be able to use VPC endpoints to avoid the need for public connectivity.
Unfortunately, as you've noted, these solutions typically cost more than simply using a public IPv4 address. The NAT Gateway in particular has both hourly and data processing charges.
If cost is your primary concern and you're only looking at a small number of instances, keeping the public IPv4 addresses might indeed be the most cost-effective approach for now. AWS continues to expand IPv6 support across services, but there are still gaps that make a complete transition challenging without incurring other costs.
For a truly cost-optimized approach, you might need to evaluate the specific scale of your deployment to determine the crossover point where NAT Gateway costs become less than multiple public IPv4 address charges.
Sources
IPv6 support in AWS | AWS re:Post
Connecting IPv4-only Windows clients to IPv6 EC2 Windows and Linux servers | AWS re:Post
answered 10 months ago
Relevant content
asked 2 years ago
asked 3 years ago
- AWS OFFICIALUpdated a year ago

All of these options are costlier than a public IPv4