Repository: getmoto/moto

Issue:
Improvement: Cloudformation responses always have a hardcoded `CreationDate`
Whilst using Localstack (which uses this framework) whenever responses are returned through the CLI the creationdate fields are always a fixed value in the past. eg. the LIST_STACKS_RESPONSE (in moto/cloudformation/models.py) contains the `CreationDate` value `2011-05-23T15:47:44Z`.

Expected behaviour;
A proper timestamp is generated and passed to the response (for instance {{ stack.creation_time }} ). 

Note: Localstack has fixed this issue by replacing the response body as seen in [this pull request](https://github.com/localstack/localstack/pull/2103/files) but a fix in the underlying framework would be the best way to go


Discussion:
Welcome to moto, @garkenbout-quintor! Thanks for raising this -  I've marked it as an enhancement. 

Off-topic: Is that Quintor in Groningen? If so, small world! I used to work there from 2011-2013 :) 
Off-topic; Technically The Hague Quintor, but correct ;) small world indeed!

On-topic; Thanks for marking this, gonna follow the progress ;) (was gonna try and make the improvement, but not being familiar with the codebase makes it a bit more difficult for a quick fix)
There was already a PR for this, but that obviously needs some love: #1310

Could be a good starting point for people who want to pick this up

Resolving patch:
diff --git a/moto/cloudformation/models.py b/moto/cloudformation/models.py
--- a/moto/cloudformation/models.py
+++ b/moto/cloudformation/models.py
@@ -8,6 +8,7 @@
 
 from moto.compat import OrderedDict
 from moto.core import BaseBackend, BaseModel
+from moto.core.utils import iso_8601_datetime_without_milliseconds
 
 from .parsing import ResourceMap, OutputMap
 from .utils import (
@@ -240,6 +241,7 @@ def __init__(
         self.output_map = self._create_output_map()
         self._add_stack_event("CREATE_COMPLETE")
         self.status = "CREATE_COMPLETE"
+        self.creation_time = datetime.utcnow()
 
     def _create_resource_map(self):
         resource_map = ResourceMap(
@@ -259,6 +261,10 @@ def _create_output_map(self):
         output_map.create()
         return output_map
 
+    @property
+    def creation_time_iso_8601(self):
+        return iso_8601_datetime_without_milliseconds(self.creation_time)
+
     def _add_stack_event(
         self, resource_status, resource_status_reason=None, resource_properties=None
     ):
diff --git a/moto/cloudformation/responses.py b/moto/cloudformation/responses.py
--- a/moto/cloudformation/responses.py
+++ b/moto/cloudformation/responses.py
@@ -662,7 +662,7 @@ def update_stack_instances(self):
       <member>
         <StackName>{{ stack.name }}</StackName>
         <StackId>{{ stack.stack_id }}</StackId>
-        <CreationTime>2010-07-27T22:28:28Z</CreationTime>
+        <CreationTime>{{ stack.creation_time_iso_8601 }}</CreationTime>
         <StackStatus>{{ stack.status }}</StackStatus>
         {% if stack.notification_arns %}
         <NotificationARNs>
@@ -803,7 +803,7 @@ def update_stack_instances(self):
         <StackId>{{ stack.stack_id }}</StackId>
         <StackStatus>{{ stack.status }}</StackStatus>
         <StackName>{{ stack.name }}</StackName>
-        <CreationTime>2011-05-23T15:47:44Z</CreationTime>
+        <CreationTime>{{ stack.creation_time_iso_8601 }}</CreationTime>
         <TemplateDescription>{{ stack.description }}</TemplateDescription>
     </member>
     {% endfor %}


Test patch:
diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
--- a/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_crud_boto3.py
@@ -2,6 +2,8 @@
 
 import json
 from collections import OrderedDict
+from datetime import datetime, timedelta
+import pytz
 
 import boto3
 from botocore.exceptions import ClientError
@@ -911,6 +913,10 @@ def test_describe_stack_by_name():
 
     stack = cf_conn.describe_stacks(StackName="test_stack")["Stacks"][0]
     stack["StackName"].should.equal("test_stack")
+    two_secs_ago = datetime.now(tz=pytz.UTC) - timedelta(seconds=2)
+    assert (
+        two_secs_ago < stack["CreationTime"] < datetime.now(tz=pytz.UTC)
+    ), "Stack should have been created recently"
 
 
 @mock_cloudformation