Source code for idem_aws.states.aws.config.config_recorder

"""State module for managing Amazon Config Recorder."""
import copy
from dataclasses import field
from dataclasses import make_dataclass
from typing import Any
from typing import Dict
from typing import List

__contracts__ = ["resource"]

TREQ = {
    "absent": {
        "require": [
            "aws.config.delivery_channel.present",
        ],
    },
}


[docs]async def present( hub, ctx, name: str, role_arn: str, recording_group: make_dataclass( "ConfigurationRecorder", [ ("allSupported", bool, field(default=None)), ("includeGlobalResourceTypes", bool, field(default=None)), ("resourceTypes", List[str], field(default=None)), ], ), resource_id: str = None, ) -> Dict[str, Any]: """Creates a new configuration recorder to record the selected resource configurations. Args: name(str): The name of the recorder. role_arn (str): Amazon Resource Name (ARN) of the IAM role used to describe the Amazon Web Services resources associated with the account. recording_group (dict[str, Any], Optional): Specifies the types of Amazon Web Services resources for which Config records configuration changes. * allSupported (bool, Optional): Specifies whether Config records configuration changes for every supported type of regional resource. If you set this option to true, when Config adds support for a new type of regional resource, it starts recording resources of that type automatically. If you set this option to true, you cannot enumerate a list of resourceTypes. * includeGlobalResourceTypes (bool, Optional): Specifies whether Config includes all supported types of global resources (for example, IAM resources) with the resources that it records. Before you can set this option to true, you must set the allSupported option to true. If you set this option to true, when Config adds support for a new type of global resource, it starts recording resources of that type automatically. The configuration details for any global resource are the same in all regions. To prevent duplicate configuration items, you should consider customizing Config in only one region to record global resources. * resourceTypes (list[str], Optional): A comma-separated list that specifies the types of Amazon Web Services resources for which Config records configuration changes (for example, AWS::EC2::Instance or AWS::CloudTrail::Trail). To record all configuration changes, you must set the allSupported option to true. If you set this option to false, when Config adds support for a new type of resource, it will not record resources of that type unless you manually add that type to your recording group. For a list of valid resourceTypes values, see the resourceType Value column in Supported Amazon Web Services resource Types. resource_id (str, Optional): The name of the recorder. Request syntax: .. code-block:: sls [aws-config-recorder]: aws.config.config_recorder.present: - name: 'string' - resource_id: 'string' - role_arn: 'string' - recording_group: 'dict' Returns: Dict[str, Any] Examples: .. code-block:: sls aws-config-recorder: aws.config.config_recorder.present: - name: 'config_recorder' - resource_id: 'config_recorder' - role_arn: 'arn:aws:iam::012345678912:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig' - recording_group: allSupported: false includeGlobalResourceTypes: false resourceTypes: - "AWS::ApiGateway::Stage" """ result = dict(comment=[], old_state=None, new_state=None, name=name, result=True) before = None resource_updated: bool = True if resource_id: resource = await hub.exec.boto3.client.config.describe_configuration_recorders( ctx, ConfigurationRecorderNames=[name], ) if not resource["result"]: result["comment"] = resource["comment"] result["result"] = False return result else: before = resource["ret"]["ConfigurationRecorders"][0] if before: resource_translated = ( hub.tool.aws.config.conversion_utils.convert_raw_config_recorder_to_present( ctx, raw_resource=before ) ) result["old_state"] = resource_translated resource_updated = await hub.tool.aws.config.config_utils.is_resource_updated( before=resource_translated, role_arn=role_arn, recording_group=recording_group, ) if ctx.get("test", False): result["new_state"] = hub.tool.aws.test_state_utils.generate_test_state( enforced_state={}, desired_state={ "name": name, "role_arn": role_arn, "resource_id": resource_id, "recording_group": recording_group, }, ) operation = "update" if before else "create" if before: if resource_updated: result["comment"] += [ f"Would {operation} aws.config.config_recorder '{name}'" ] else: result["comment"] += [ f"aws.config.config_recorder '{name}' already exists" ] else: result["comment"] += [ f"Would {operation} aws.config.config_recorder '{name}'" ] return result if resource_updated: update_ret = await hub.exec.boto3.client.config.put_configuration_recorder( ctx=ctx, ConfigurationRecorder={ "name": name, "roleARN": role_arn, "recordingGroup": recording_group, }, ) if not update_ret["result"]: result["comment"] = update_ret["comment"] result["result"] = False return result after_ret = await hub.exec.boto3.client.config.describe_configuration_recorders( ctx, ConfigurationRecorderNames=[name], ) if not after_ret["result"]: result["comment"] = after_ret["comment"] result["result"] = False return result result[ "new_state" ] = hub.tool.aws.config.conversion_utils.convert_raw_config_recorder_to_present( ctx, raw_resource=after_ret["ret"]["ConfigurationRecorders"][0] ) operation = "Created" if not before else "Updated" result["comment"] += [f"{operation} aws.config.config_recorder '{name}'"] else: result["comment"] += [f"aws.config.config_recorder '{name}' already exists"] result["new_state"] = copy.deepcopy(result["old_state"]) return result
[docs]async def absent(hub, ctx, name: str, resource_id: str = None) -> Dict[str, Any]: """Deletes the configuration recorder. After the configuration recorder is deleted, Config will not record resource configuration changes until you create a new configuration recorder. Args: name(str): The name of the recorder. resource_id(str, Optional): AWS Config configuration recorder Name. Idem automatically considers this resource being absent if this field is not specified. Returns: Dict[str, Any] Examples: .. code-block:: sls aws-config-recorder: aws.config.config_recorder.absent: - name: 'config_recorder' - resource_id: 'config_recorder' """ result = dict(comment=[], old_state=None, new_state=None, name=name, result=True) before = None if not resource_id: result["comment"] = hub.tool.aws.comment_utils.already_absent_comment( resource_type="aws.config.config_recorder", name=name ) return result resource = await hub.exec.boto3.client.config.describe_configuration_recorders( ctx, ConfigurationRecorderNames=[name], ) if not resource["result"]: if "NoSuchConfigurationRecorderException" in str(resource["comment"]): result["comment"] = hub.tool.aws.comment_utils.already_absent_comment( resource_type="aws.config.config_recorder", name=name ) return result result["comment"] = resource["comment"] result["result"] = False return result before = resource["ret"]["ConfigurationRecorders"][0] if before: translated_resource = ( hub.tool.aws.config.conversion_utils.convert_raw_config_recorder_to_present( ctx, raw_resource=before ) ) result["old_state"] = translated_resource else: result["comment"] = hub.tool.aws.comment_utils.already_absent_comment( resource_type="aws.config.config_recorder", name=name ) return result if ctx.get("test", False): result["comment"] = hub.tool.aws.comment_utils.would_delete_comment( resource_type="aws.config.config_recorder", name=name ) return result else: delete_ret = await hub.exec.boto3.client.config.delete_configuration_recorder( ctx, ConfigurationRecorderName=name ) result["result"] = delete_ret["result"] if not result["result"]: result["comment"] = delete_ret["comment"] return result result["comment"] = hub.tool.aws.comment_utils.delete_comment( resource_type="aws.config.config_recorder", name=name ) return result
[docs]async def describe(hub, ctx) -> Dict[str, Dict[str, Any]]: """Describe the resource in a way that can be recreated/managed with the corresponding "present" function. Return details about your config recorder. Returns: Dict[str, Any] Examples: .. code-block:: bash $ idem describe aws.config.config_recorder """ result = {} ret = await hub.exec.boto3.client.config.describe_configuration_recorders(ctx) if not ret["result"]: hub.log.warning(f"Could not describe configuration recorder {ret['comment']}") return {} for resource in ret["ret"]["ConfigurationRecorders"]: name = resource["name"] recorder_name = f"{name}-config-recorder" translated_resource = ( hub.tool.aws.config.conversion_utils.convert_raw_config_recorder_to_present( ctx, raw_resource=resource ) ) result[recorder_name] = { "aws.config.config_recorder.present": [ {parameter_key: parameter_value} for parameter_key, parameter_value in translated_resource.items() ] } return result