Repository: cloud-custodian/cloud-custodian

Issue:
Add ability to copy RDS DB Instance tags to snapshots
It would be great to set the RDS DB Instance `CopyTagsToSnapshot` flag as a parameter to the RDS `retention` action.
How about adding a boolean `copy-tags` attribute (default to **false** to keep compatibility)?



Discussion:

Resolving patch:
diff --git a/c7n/resources/rds.py b/c7n/resources/rds.py
--- a/c7n/resources/rds.py
+++ b/c7n/resources/rds.py
@@ -274,7 +274,9 @@ def process_rds_snapshot(self, resource):
 class RetentionWindow(BaseAction):
 
     date_attribute = "BackupRetentionPeriod"
-    schema = type_schema('retention', days={'type': 'number'})
+    schema = type_schema(
+        'retention',
+        **{'days': {'type': 'number'}, 'copy-tags': {'type': 'boolean'}})
 
     def process(self, resources):
         with self.executor_factory(max_workers=3) as w:
@@ -290,17 +292,26 @@ def process(self, resources):
                                 f.exception()))
 
     def process_snapshot_retention(self, resource):
-        v = int(resource.get('BackupRetentionPeriod', 0))
-        if ((v == 0 or v < self.data['days']) and
+        current_retention = int(resource.get('BackupRetentionPeriod', 0))
+        current_copy_tags = resource['CopyTagsToSnapshot']
+        new_retention = self.data['days']
+        new_copy_tags = self.data.get('copy-tags', False)
+
+        if ((current_retention < new_retention or
+                current_copy_tags != new_copy_tags) and
                 self._db_instance_eligible_for_backup(resource)):
-            self.set_retention_window(resource)
+            self.set_retention_window(
+                resource,
+                max(current_retention, new_retention),
+                new_copy_tags)
             return resource
 
-    def set_retention_window(self, resource):
+    def set_retention_window(self, resource, retention, copy_tags):
         c = local_session(self.manager.session_factory).client('rds')
         c.modify_db_instance(
             DBInstanceIdentifier=resource['DBInstanceIdentifier'],
-            BackupRetentionPeriod=self.data['days'])
+            BackupRetentionPeriod=retention,
+            CopyTagsToSnapshot=copy_tags)
 
     def _db_instance_eligible_for_backup(self, resource):
         db_instance_id = resource['DBInstanceIdentifier']


Test patch:
diff --git a/tests/test_rds.py b/tests/test_rds.py
--- a/tests/test_rds.py
+++ b/tests/test_rds.py
@@ -117,6 +117,18 @@ def test_rds_retention(self):
         resources = p.run()
         self.assertEqual(len(resources), 6)
 
+    def test_rds_retention_copy_tags(self):
+        session_factory = self.replay_flight_data('test_rds_retention')
+        p = self.load_policy(
+            {'name': 'rds-snapshot',
+             'resource': 'rds',
+             'actions': [
+                 {'type': 'retention', 'days': 21, 'copy-tags': True}]},
+            config={'region': 'us-west-2'},
+            session_factory=session_factory)
+        resources = p.run()
+        self.assertEqual(len(resources), 6)
+
     def test_rds_delete(self):
         session_factory = self.replay_flight_data('test_rds_delete')
         p = self.load_policy(