.. _c7n_functions: ###################### C7N Functions Required ###################### This survey of C7N filter clauses is based on source code and on an analysis of working policies. The required functions are grouped into four clusters, depending on the presence of absence of the "op" operator clause, and the number of resource types using the feature. Within each group, they are ranked in order of popularity. For each individual type of filter clause, we provide the following details: - The C7N sechema definition. - The resource types where the filter type is used. - The variant implementations that are registered (if any.) - If used in the working policies, - the number of policies using the filter clause, - Up to three examples. The actions are redacted as are specific values from filters. The filter redaction obscures the S3 buckets, RESTful services, vpc-names, tag values, and subnet names. The schema and the examples help to define the domain of CEL functions required. .. contents:: Contents Design Principles ================= There are a number of general design principles that apply to the C7N-CEL interface. 1. Separate from C7N. The CEL processing is outside C7N, and capable of standing alone. CEL is focused on Protobuf (and JSON) objects. The interface to C7N is via the :mod:`c7nlib` library of functions. These do **not** depend on imports from the C7N project, but rely on a `CELFilter` class offering specific methods. Access to C7N objects and their associated methods is limited to the features exposed through the function library and the expected class definition. 2. Resource Representation. CEL is focused on Protobuf (and JSON) objects. This means cloud resource descriptions must be provided in this form. For AWS resource descriptions, this works out well since they start as JSON documents. For C7N it works out well because the C7N representation of a resource is a Python dictionary. 3. The CEL activation context has these expected objects: :resource: This is the cloud resource being examined by C7N. This will be a CEL mapping object built from JSON source data. :now: This is the current time. This will be a CEL timestamp. This promotes testability by removing the need to mock a clock to provide proper ``utcnow()`` values. :event: For lambda-related resources, this is the triggering event. This will be a CEL mapping object built from JSON source data. 4. C7N Extension functions can rely on a global ``C7N`` object. This is the :py:class:`celpy.c7nlib.C7NContext` instance used to manage C7N CEL Execution. It generally has one attribute, ``filter`` which is the current ``CELFilter`` instance. C7N Context Object ================== A global ``C7N`` object in the :py:mod:`celpy.c7nlib` module contains a reference to the current ``CELFilter`` instance. This has a single attribite. - ``C7N.filter`` is the current :py:class:`CELFilter` instance. This is a subclass of :py:class:`c7n.filters.core.Filter`. It provides the resource manager, useful to getting cloud provider client connections. The ``C7N.filter.manager`` can be used to gather additional cloud provider data. In many cases, a number of additional functions are also present in this class. A number of filter expressions rely on data not directly avalable in the ``resource`` or ``event`` objects. These are called *related resource* filters, and there are several examples. - ``type: image`` and ``type: image-age`` filters gather details about the image associated with a resource like an ec2. These filter types are handled by the :func:`c7nlib.image` function. This uses ``C7N.filter.get_instance_image()``. The :py:class:`CELFilter` implementation should be a mixin shared by the C7N :py:class:`ImageAge` class. - ``type: metrics`` filter provides metrics information for those resources that create CloudWatch metrics. This filter type is handled by the :func:`c7nlib.get_raw_metrics` and :func:`c7nlib.get_metrics` functions. This uses methods extracted from the C7N :py:class:`Metrics` filter class. It also uses the ``C7N.filter.manager.get_model()`` and ``C7N.filter.manager.resource_type``. - ``type: security-group`` filter gathers the security group details and security group IDs. These filter types are handled by the :func:`c7nlib.security_group` and :func:`c7nlib.get_related_ids` functions. These use ``C7N.filter.get_related_ids()`` and ``C7N.filter.get_related()`` functions. The :py:class:`CELFilter` implementation should be the C7N :py:class:`RelatedResourceFilter` class. - ``type: subnet`` filter gathers the subnet details. This filter type is handled by the :func:`c7nlib.subnet` function. This uses the ``C7N.filter.get_related()`` function. The :py:class:`CELFilter` implementation should be the C7N :py:class:`RelatedResourceFilter` class. - ``type: flow-logs`` filter gathers the flow logs from those resources that support this kind of logging. This filter type is handled by the :func:`c7nlib.flow_logs` function. This uses code extracted from the C7N ``vpc.FlowLogFilter`` class. The :py:class:`CELFilter` implementation should be the C7N :py:class:`vpc.FlowLogFilter` class. - ``type: vpc`` filter gather information about the VPC's used to host resources. This filter type is handled by the :func:`c7nlib.vpc` function. This uses the ``C7N.filter.get_related()`` function. The :py:class:`CELFilter` implementation should be the C7N :py:class:`RelatedResourceFilter` class. - ``type: credentials`` filter gathers information about IAM role credentials. This filter type is handled by the :func:`c7nlib.credentials` function. This uses the ``C7N.filter.get_credential_report()`` function. The :py:class:`CELFilter` implementation should be a mixin shared by the C7N :py:class:`iam.CredentialReport` class. - ``type: kms-alias`` filter gathers information about KMS alias attributes. This filter type is handled by the :func:`c7nlib.kms_alias` function. This uses the ``C7N.filter.get_matching_aliases()`` function. The :py:class:`CELFilter` implementation should be the mixin shared by the C7N :py:class:`ebs.KmsKeyAlias` class. - ``type: kms-key`` filter gathers information about KMS key attributes. This filter type is handled by the :func:`c7nlib.kms_key` function. This uses the ``C7N.filter.get_related()`` function. The :py:class:`CELFilter` implementation should be the C7N :py:class:`RelatedResourceFilter` class. Note that this implies refactoring of C7N filters to provide a unified access to a number of pieces of data from a single ``CELFilter`` class. Currently, the functionality is scattered among several :py:class:`Filter` subclasses and mixins. CELFilter Design ================= This processing must be refactored into a :py:class:`CELFilter` subclass of :py:class:`Filter`. All the mixins currently part of more specialized filters need to be collected into this class. In some cases, functionality must be extracted from existing filters to create mixins which can be shared by the :py:class:`CELFilter` class. For example, t:py:class:`ImageAge` filter is a composite, built from :py:class:`AgeFilter` and :py:class:`InstanceImageBase`. In this case, the :py:class:`c7n.resources.ec2.InstanceImageBase` class gathers AMI image details. The :py:class:`CELFilter` needs to have the :py:class:`InstanceImageBase` mixin available to gather the required data for the CEL operation. This is a subclass of Subclass of c7n.filters.core.Filter. See the :py:mod:`celpy.c7nlib` module for additional information on this interface. :: class InstanceImageMixin: # from :py:class:`InstanceImageBase` refactoring def get_instance_image(self): pass class RelatedResourceMixin: # from :py:class:`RelatedResourceFilter` mixin def get_related_ids(self): pass def get_related(self): pass class CredentialReportMixin: # from :py:class:`c7n.resources.iam.CredentialReport` filter. def get_credential_report(self): pass class ResourceKmsKeyAliasMixin: # from :py:class:`c7n.resources.kms.ResourceKmsKeyAlias` def get_matching_aliases(self, resource): pass class CrossAccountAccessMixin: # from :py:class:`c7n.filters.iamaccessfilter.CrossAccountAccessFilter` def get_accounts(self, resource): pass def get_vpcs(self, resource): pass def get_vpces(self, resource): pass def get_orgids(self, resource): pass # from :py:class:`c7n.resources.secretsmanager.CrossAccountAccessFilter` def get_resource_policy(self, resource): pass class SNSCrossAccountMixin: # from :py:class:`c7n.resources.sns.SNSCrossAccount` def get_endpoints(self, resource): pass def get_protocols(self, resource): pass class ImagesUnusedMixin: # from :py:class:`c7n.resources.ami.ImageUnusedFilter` def _pull_ec2_images(self, resource): pass def _pull_asg_images(self, resource): pass class SnapshotUnusedMixin: # from :py:class:`c7n.resources.ebs.SnapshotUnusedFilter` def _pull_asg_snapshots(self, resource): pass def _pull_ami_snapshots(self, resource): pass class IamRoleUsageMixin: # from :py:class:`c7n.resources.iam.IamRoleUsage` def service_role_usage(self, resource): pass def instance_profile_usage(self, resource): pass class SGUsageMixin: # from :py:class:`c7n.resources.vpc.SGUsage` def scan_groups(self, resource): pass class IsShieldProtectedMixin: # from :py:mod:`c7n.resources.shield` def get_type_protections(self, resource): pass class ShieldEnabledMixin: # from :py:class:`c7n.resources.account.ShieldEnabled` def account_shield_subscriptions(self, resource): pass class CELFilter( InstanceImageMixin, RelatedResourceMixin, CredentialReportMixin, ResourceKmsKeyAliasMixin, CrossAccountAccessMixin, SNSCrossAccountMixin, ImagesUnusedMixin, SnapshotUnusedMixin, IamRoleUsageMixin, SGUsageMixin, c7n.filters.core.Filter, ): """ State a filter as a CEL expression. The activation environment for CEL has all the functions in ``c7nlib``. It also includes three global objects: - ``resource`` the cloud resource to be examined. - ``now`` the current time as a CEL timestamp. - ``event`` an event for those resources where the C7N check is triggered by a CloudWatch event. """ schema = type_schema( 'cel', 'type': {'enum': ['cel']}, 'expr': {'type': 'string'} ) decls: Dict[str, celpy.Annotation] = { "resource": celpy.celtypes.MapType, "now": celpy.celtypes.TimestampType, "event": celpy.celtypes.MapType, } decls.update(celpy.c7nlib.DECLARATIONS) env = celpy.Environment(annotations=CELFilter.decls) def __init__(self, data, manager) -> None: super().__init__(data, manager) assert data["type"].lower() == "cel" self.expr = data["expr"] self.parser = c7n.filters.offhours.ScheduleParser() def validate(self) -> None: """Compile and build CEL""" cel_env = celpy.Environment( annotations=self.decls, runner_class=c7nlib.C7N_Interpreted_Runner) cel_ast = cel_env.compile(self.expr) self.pgm = cel_env.program(cel_ast, functions=celpy.c7nlib.FUNCTIONS) def process(self, resources: Iterable[celpy.celtypes.MapType]) -> Iterator[celpy.celtypes.MapType]: """Apply CEL to the various resources.""" now = datetime.datetime.utcnow() for resource in resources: with C7NContext(filter=the_filter): cel_activation = { "resource": celpy.json_to_cel(resource), "now": celpy.celtypes.TimestampType(now), # "event": ..., } if self.pgm.evaluate(cel_activation): yield resource This is a suggested interface. It seems to fit the outline of many other filters. It's not perfectly clear how event-based filters fit this model. C7N Cache ========== Within C7N, related resource information is cached to avoid repeatedly looking it up. The CEL activation makes use of these caches through several global objects. - The ``Resource`` provided is a JSON-to-CEL mapping of the original C7N dictionary. - The ``C7NContext`` instance is used by The CEL functions in the :py:mod:`c7nlib` module to access c7n modules and classes. This allows them to use C7N's caching and avoid extra describe operations. *All* cloud resource access must go through existing C7N ``CELFilter`` methods and resource caches. Common C7N Constructs ===================== The C7N shorthand ``tag:Name`` doesn't translate well to CEL. It extracts a single value from a sequence of objects with a ``{"Key": x, "Value": y}`` structure; specifically, the value for ``y`` when ``x == "Name"``. If we want to check the value associated with the "Uptime" tag to see if it is in some list of valid values, we have something like this. :: Resource["Tags"].filter(x, x["Key"] == "Name")[0]["Value"] This seems bulky, but it's workable within the CEL language. We can replace this with a ``key(Resource, "Name")`` function. This can be used as ``Resource["Tags"].key("Name")`` preserving the original C7N syntax to an extent. It has the ``{"Key": x, "Value": y}`` assumption wired-in. Common/Non-Bool Filters ======================= These are functions that provide data that is not trivially a boolean decision. Because an explicit ``op:`` is provided in C7N, we can map this to an CEL operator. This leads us to a function to extract data from the C7N resource description, in a form that CEL can use. value ----- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['value']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ssm-managed-instance, aws.iam-policy, aws.batch-definition, aws.iam-group, aws.shield-protection, aws.ecs, aws.fsx-backup, aws.ecs-container-instance, aws.eks, aws.support-case, aws.vpc, aws.rds-subscription, aws.network-addr, aws.message-broker, aws.redshift, aws.sagemaker-notebook, aws.glue-connection, aws.directory, aws.ebs-snapshot, aws.rds-cluster-param-group, aws.customer-gateway, aws.lambda-layer, aws.ecs-task, aws.subnet, aws.ec2, aws.cfn, aws.cloud-directory, aws.r53domain, aws.transit-gateway, aws.sns, aws.iam-role, aws.kinesis-analytics, aws.rds-param-group, aws.snowball-cluster, aws.codebuild, aws.efs, aws.elasticbeanstalk, aws.cache-snapshot, aws.security-group, aws.waf-regional, aws.dynamodb-table, aws.kms-key, aws.step-machine, aws.s3, aws.eni, aws.snowball, aws.elasticbeanstalk-environment, aws.lambda, aws.alarm, aws.ami, aws.sagemaker-endpoint-config, aws.app-elb-target-group, aws.simpledb, aws.hsm-client, aws.directconnect, aws.nat-gateway, aws.sagemaker-job, aws.emr, aws.glue-dev-endpoint, aws.rest-account, aws.fsx, aws.rest-resource, aws.codepipeline, aws.dlm-policy, aws.rds-cluster-snapshot, aws.hsm-hapg, aws.ecs-task-definition, aws.firehose, aws.secrets-manager, aws.asg, aws.rest-vpclink, aws.vpc-endpoint, aws.redshift-subnet-group, aws.iam-profile, aws.transit-attachment, aws.rest-stage, aws.rest-api, aws.distribution, aws.cache-subnet-group, aws.ecs-service, aws.event-rule-target, aws.identity-pool, aws.ssm-activation, aws.rds-snapshot, aws.app-elb, aws.ecr, aws.peering-connection, aws.ebs, aws.config-rule, aws.dax, aws.kinesis, aws.rrset, aws.batch-compute, aws.kms, aws.cloudtrail, aws.dynamodb-backup, aws.dms-endpoint, aws.sqs, aws.sagemaker-endpoint, aws.gamelift-build, aws.shield-attack, aws.dms-instance, aws.backup-plan, aws.key-pair, aws.iot, aws.hostedzone, aws.log-group, aws.rds-subnet-group, aws.cache-cluster, aws.hsm, aws.vpn-gateway, aws.sagemaker-transform-job, aws.route-table, aws.dynamodb-stream, aws.redshift-snapshot, aws.efs-mount-target, aws.codecommit, aws.glacier, aws.elasticsearch, aws.event-rule, aws.ssm-parameter, aws.rds, aws.sagemaker-model, aws.account, aws.cloudhsm-cluster, aws.waf, aws.vpn-connection, aws.iam-certificate, aws.iam-user, aws.streaming-distribution, aws.ml-model, aws.network-acl, aws.health-event, aws.launch-config, aws.rds-cluster, aws.storage-gateway, aws.healthcheck, aws.opswork-cm, aws.opswork-stack, aws.user-pool, aws.acm-certificate, aws.datapipeline, aws.elb, aws.gamelift-fleet, aws.cloudsearch, aws.internet-gateway No implementation for value. Policies studied have 5103 examples. .. code:: yaml name: asg-invalid-asv-value-notify comment: Report on any ASGs that use an ASV that isn't valid. resource: asg filters: - tag:custodian_asv: not-null - key: tag:ASV op: not-in type: value value_from: expr: all_values.* format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: parent-asg-ancient-image-delete comment: Delete any ASG that uses an AMI that is over 60 days old. resource: asg filters: - LaunchConfigurationName: not-null - tag:OwnerContact: not-null - key: tag:ASV op: not-in type: value value: null - key: tag:ASV op: not-in type: value value: - ASVredacted - days: 60 op: ge type: image-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: parent-asg-ancient-image-delete comment: Delete any ASG that uses an AMI that is over 60 days old. resource: asg filters: - LaunchConfigurationName: not-null - tag:OwnerContact: not-null - key: tag:ASV op: not-in type: value value: null - key: tag:ASV op: not-in type: value value: - ASVredacted - days: 60 op: ge type: image-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket actions: # REDACTED # The ``type: value`` clauses are the base case. There's nothing particularly special of complex here. These are handled directly by translating the C7N ``op:`` field to a CEL operator. op Implementations ------------------- .. csv-table:: :header: C7N,CEL 'eq', == 'equal', == 'ne', != 'not-equal', != 'gt', > 'greater-than', > 'ge', >= 'gte', >= 'le', < 'lte', <= 'lt', < 'less-than', < 'glob', * 'regex', string.matches(regex) 'in', string.contains(item) list.contains(item) 'ni', ~string.contains(item) ~list.contains(item) 'not-in', ~string.contains(item) ~list.contains(item) 'contains', string.contains(item) list.contains(item) 'difference', * 'intersect', * There are three additional functions required: - :py:func:`c7nlib.glob` to implement ``fnmatch.fnmatch(value, pattern)``. - :py:func:`c7nlib.difference` - :py:func:`c7nlib.intersect` value_type Conversions ---------------------- This is part of the ``value`` filter expression. There are several value type conversions performed. These are generally implemented in :meth:`c7n.filters.core.ValueFilter.process_value_type` This accepts sentinel (from the filter) and value (from the resource). It returns two values: the sentinel and, generally, a converted value that should have the same type as the resource. - 'age' -- ``parse_date(value), datetime.datetime.now(tz=tzutc()) - timedelta(sentinel)`` Note that these are reversed to make it easier to compare age against a given value. A global ``Now`` variable removes the need for an implicit age computation. The :func:`parse_date` is the :func:`pendulum.parse` function. - 'integer' -- ``sentinel, int(str(value).strip())`` - 'expiration' -- ``datetime.datetime.now(tz=tzutc()) + timedelta(sentinel), parse_date(value)`` A global ``Now`` variable removes the need for an implicit expiration computation. The :func:`parse_date` is the :func:`pendulum.parse` function. - 'normalize' -- ``sentinel, value.strip().lower()`` - 'size' -- ``sentinel, len(value)`` - 'cidr' -- ``parse_cidr(sentinel), parse_cidr(value)`` See ``from c7n.utils import set_annotation, type_schema, parse_cidr`` (It appears this is not used.) - 'cidr_size' -- ``sentinel, parse_cidr(value).prefixlen`` (It appears this is used rarely and is always part of a Cidr: filter primitive.) - 'swap' -- ``value, sentinel`` This is needed because the implied order of DSL operands. Without ``swap``, the operation is *resource OP filter-value*. With ``swap`` it's *filter-value OP resource*. - 'unique_size' -- ``len(set(value))`` (It appears this is not used.) - 'date' -- ``parse_date(sentinel), parse_date(value)`` (It appears this is not used.) - 'version' -- ``ComparableVersion(sentinel), ComparableVersion(value)`` (It appears this is not used.) The following are unusual value_type options. They're part of the schema, but have special-seeming implementations but aren't widely used. - 'expr' -- ``self.get_resource_value(sentinel, resource)`` This seems to be widely used used in an action context and in a ``value_from`` element of a ``value`` clause. It does not appear to be a general feature of filters. - 'resource_count' -- the op is applied to len(resources) instead of the resources. This is handled specially in the :class:`filters.core.ValueFilter` class. Some of these are directly available in CEL. See https://github.com/google/cel-spec/blob/master/doc/langdef.md#list-of-standard-definitions. .. csv-table:: :header: C7N,CEL 'age', duration() 'integer', int() 'expiration', duration() 'normalize', * 'size', size() 'cidr', * 'cidr_size', * 'expr', this is generally resource[value] 'unique_size', size(set(value)) 'date', timestamp() 'version', * 'resource_count', * Additional functions are needed for a few of these operations: - :py:func:`c7nlib.normalize` - :py:func:`c7nlib.unique_size` - :py:func:`c7nlib.parse_cidr` - :py:func:`c7nlib.size_parse_cidr` - :py:func:`c7nlib.version` - :py:func:`c7nlib.present` - :py:func:`c7nlib.absent` It would be sensible to follow some of the design patterns used by OPA for these extensions. See https://www.openpolicyagent.org/docs/latest/policy-reference/#net for examples of CIDR-parsing. 'swap' is not needed because CEL allows reordering operands. value_from External Data ------------------------- There are several sources for values other than literal values. This is defined by a ``values_from`` sub-clause. The sub-clause includes up to three additional parameters :url: A URL points at the source of the data: S3 or HTTPS. :format: One of json, csv, csv2dict, txt. This can be inferred from the suffix on the path in the URL. :expr: This extracts specific fields from the raw data. Expression syntax: - on json, a jmespath expr is evaluated. - on csv, an integer column or jmespath expr can be specified. - on csv2dict, a jmespath expr (the csv is parsed into a dictionary where the keys are the headers and the values are the remaining columns). Text files are expected to be line delimited values. While CEL doesn't directly use JMESPath, it has some similarities. We can use a :py:func:`celpy.c7nlib.jmes_path` function to explicitly handle C7N JMESPath. We can also use the existing ``map()`` macro for simpler cases, like extracting a column from a CSV. C7N Examples:: value_from: url: s3://bucket/xyz/foo.json expr: [].AppId values_from: url: http://foobar.com/mydata format: json expr: Region."us-east-1"[].ImageId value_from: url: s3://bucket/abc/foo.csv format: csv2dict expr: key[1] # inferred from extension format: [json, csv, csv2dict, txt] (Yes, there's a spelling mistake in one of the examples.) Proposed CEL Examples:: value_from("s3://bucket/xyz/foo.json").map(x, x.AppId) value_from("http://foobar.com/mydata", "json").jmes_path('Region.["us-east-1"]').map(x, x.ImageId) value_from("s3://bucket/abc/foo.csv").map(x, x[1]) This requires a suite of functions: - :py:func:`c7nlib.text_from` - :py:func:`c7nlib.parse_text` - :py:func:`c7nlib.value_from` - :py:func:`c7nlib.jmes_path` - :py:func:`c7nlib.jmes_path_map` marked-for-op ------------- Schema .. code:: yaml op: {'type': 'string'} skew: {'type': 'number', 'minimum': 0} skew_hours: {'type': 'number', 'minimum': 0} tag: {'type': 'string'} type: {'enum': ['marked-for-op']} tz: {'type': 'string'} Used by aws.fsx, aws.hostedzone, aws.log-group, aws.cache-cluster, aws.secrets-manager, aws.fsx-backup, aws.efs, aws.vpn-gateway, aws.cache-snapshot, aws.asg, aws.route-table, aws.security-group, aws.vpc-endpoint, aws.redshift-snapshot, aws.dynamodb-table, aws.kms-key, aws.vpc, aws.transit-attachment, aws.rest-stage, aws.glacier, aws.s3, aws.elasticsearch, aws.distribution, aws.message-broker, aws.redshift, aws.rds, aws.sagemaker-notebook, aws.sagemaker-model, aws.ssm-parameter, aws.eni, aws.ebs-snapshot, aws.network-addr, aws.vpn-connection, aws.elasticbeanstalk-environment, aws.rds-snapshot, aws.app-elb, aws.customer-gateway, aws.iam-user, aws.lambda, aws.streaming-distribution, aws.peering-connection, aws.network-acl, aws.ebs, aws.ami, aws.sagemaker-endpoint-config, aws.app-elb-target-group, aws.kinesis, aws.rds-cluster, aws.healthcheck, aws.subnet, aws.ec2, aws.sqs, aws.sagemaker-endpoint, aws.nat-gateway, aws.datapipeline, aws.emr, aws.elb, aws.transit-gateway, aws.internet-gateway, aws.dms-instance, aws.key-pair Resource Type Implementations for {function.name}: - In :file:`c7n/resources/mq.py` 48 .. parsed-literal:: @MessageBroker.filter_registry.register(marked-for-op) class MarkedForOp Policies studied have 490 examples. .. code:: yaml name: dynamodb-untagged-delete comment: Delete any DynamoDB tables whose delete date has arrived. resource: dynamodb-table filters: - op: delete tag: custodian_tagging type: marked-for-op - or: - or: - not: - and: - or: - and: - tag:ASV: not-null - key: tag:ASV op: not-equal type: value value: '' value_type: normalize - and: - tag:BA: not-null - key: tag:BA op: not-equal type: value value: '' value_type: normalize - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - key: tag:GroupName op: not-in type: value value: - EMMO - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - or: - tag:ApplicationName: absent - tag:Environment: absent - tag:Uptime: absent - key: tag:ApplicationName op: eq type: value value: '' value_type: normalize - key: tag:Environment op: eq type: value value: '' value_type: normalize - key: tag:Uptime op: eq type: value value: '' value_type: normalize actions: # REDACTED # .. code:: yaml name: dynamodb-untagged-two-day-warning comment: Final warning for DynamoDB tables marked for delete. resource: dynamodb-table filters: - or: - and: - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - tag:OwnerEID: not-null - key: tag:OwnerEID op: not-equal type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (^[A-Za-z]{3}[0-9]{3}$) - op: delete skew: 2 tag: custodian_tagging type: marked-for-op - or: - or: - not: - and: - or: - and: - tag:ASV: not-null - key: tag:ASV op: not-equal type: value value: '' value_type: normalize - and: - tag:BA: not-null - key: tag:BA op: not-equal type: value value: '' value_type: normalize - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - key: tag:GroupName op: not-in type: value value: - EMMO - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - or: - tag:ApplicationName: absent - tag:Environment: absent - tag:Uptime: absent - key: tag:ApplicationName op: eq type: value value: '' value_type: normalize - key: tag:Environment op: eq type: value value: '' value_type: normalize - key: tag:Uptime op: eq type: value value: '' value_type: normalize actions: # REDACTED # .. code:: yaml name: dynamodb-untagged-two-day-warning-no-owner comment: Final warning for DynamoDB tables marked for delete. resource: dynamodb-table filters: - or: - tag:OwnerContact: absent - key: tag:OwnerContact op: eq type: value value: '' value_type: normalize - or: - tag:OwnerEID: absent - key: tag:OwnerEID op: eq type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (?!(^[A-Za-z]{3}[0-9]{3})$) - op: delete skew: 2 tag: custodian_tagging type: marked-for-op actions: # REDACTED # The ``type: marked-for-op`` filter is the obverse to the ``mark-for-ap`` action. Both work with a complex tag value format. :: message:action@action_date For a filter, there is a multi-step search. 1. Examine Tags, looking for the target Key (default "custodian_status"). 2. Parse the value to get the three fields: mssage, action, and action_date. 3. Examine the action to see if it matches the ``op:`` value (default "stop") 4. Compare the action_date with the current time, ``Now`` possibly offset by the ``skew:`` and ``skew_hours:`` as well as ``tz:`` values. The two comparisons (operation and date) can be exposed as basic CEL. This leaves the parsing of the tag as a feature for the interface library. The following will parse the value, creating a Mapping that can be used for subsequent processing. :: Resource["Tags"].marked_key("custodian_status") We expect something like this:: Resource["Tags"].marked_key("custodian_status").action == "stop" && Now >= Resource["Tags"].marked_key("custodian_status").action_date This will find items marked for action that are past due. This requires one new function: - :py:func:`c7nlib.marked_key` image-age --------- Schema .. code:: yaml days: {'minimum': 0, 'type': 'number'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['image-age']} Used by aws.ec2, aws.asg, aws.ami Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ami.py` 189 .. parsed-literal:: @filters.register(image-age) class ImageAgeFilter Filters images based on the age (in days) :example: .. code:: yaml policies: - name: ami-remove-launch-permissions resource: ami filters: - type: image-age days: 30 - In :file:`c7n/resources/ec2.py` 390 .. parsed-literal:: @filters.register(image-age) class ImageAge EC2 AMI age filter Filters EC2 instances based on the age of their AMI image (in days) :Example: .. code:: yaml policies: - name: ec2-ancient-ami resource: ec2 filters: - type: image-age op: ge days: 90 - In :file:`c7n/resources/asg.py` 563 .. parsed-literal:: @filters.register(image-age) class ImageAgeFilter Filter asg by image age (in days). :example: .. code-block:: yaml policies: - name: asg-older-image resource: asg filters: - type: image-age days: 90 op: ge Policies studied have 318 examples. .. code:: yaml name: parent-asg-ancient-image-delete comment: Delete any ASG that uses an AMI that is over 60 days old. resource: asg filters: - LaunchConfigurationName: not-null - tag:OwnerContact: not-null - key: tag:ASV op: not-in type: value value: null - key: tag:ASV op: not-in type: value value: - ASVredacted - days: 60 op: ge type: image-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: parent-asg-ancient-image-delete-no-owner comment: Delete any ASG that uses an AMI that is over 60 days old but has no OwnerContact info. resource: asg filters: - LaunchConfigurationName: not-null - tag:OwnerContact: absent - key: tag:ASV op: not-in type: value value: null - key: tag:ASV op: not-in type: value value: - ASVredacted - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - days: 60 op: ge type: image-age actions: # REDACTED # .. code:: yaml name: parent-ec2-ami-age-35days-notify comment: Send a warning to users when their AMI has reached 35 days of age resource: ec2 filters: - key: State.Name op: ne type: value value: terminated - days: 34.5 op: ge type: image-age - days: 35.5 op: lt type: image-age - key: tag:ASV op: not-in type: value value: null - key: tag:ASV op: not-in type: value value: - ASVredacted - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket actions: # REDACTED # A ``type: image-age`` filter examines data not directly part of the current ``Resource`` object. An EC2, or ASG has an associated AMI, named with the ``ImageId`` attribute. The AMI description has the ``CreationDate``. This is one of many examples of related resource processing. The value of ``Now - Resource.image().CreationDate`` is the image age, as a :py:class:`celtypes.DurationType` object. This requires one new function: - :py:func:`c7nlib.image` depends on :py:meth:`CELFilter.get_instance_image`. event ----- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['event']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ssm-managed-instance, aws.iam-policy, aws.batch-definition, aws.iam-group, aws.shield-protection, aws.ecs, aws.fsx-backup, aws.ecs-container-instance, aws.eks, aws.support-case, aws.vpc, aws.rds-subscription, aws.network-addr, aws.message-broker, aws.redshift, aws.sagemaker-notebook, aws.glue-connection, aws.directory, aws.ebs-snapshot, aws.rds-cluster-param-group, aws.customer-gateway, aws.lambda-layer, aws.ecs-task, aws.subnet, aws.ec2, aws.cfn, aws.cloud-directory, aws.r53domain, aws.transit-gateway, aws.sns, aws.iam-role, aws.kinesis-analytics, aws.rds-param-group, aws.snowball-cluster, aws.codebuild, aws.efs, aws.elasticbeanstalk, aws.cache-snapshot, aws.security-group, aws.waf-regional, aws.dynamodb-table, aws.kms-key, aws.step-machine, aws.s3, aws.eni, aws.snowball, aws.elasticbeanstalk-environment, aws.lambda, aws.alarm, aws.ami, aws.sagemaker-endpoint-config, aws.app-elb-target-group, aws.simpledb, aws.hsm-client, aws.directconnect, aws.nat-gateway, aws.sagemaker-job, aws.emr, aws.glue-dev-endpoint, aws.rest-account, aws.fsx, aws.rest-resource, aws.codepipeline, aws.dlm-policy, aws.rds-cluster-snapshot, aws.hsm-hapg, aws.ecs-task-definition, aws.firehose, aws.secrets-manager, aws.asg, aws.rest-vpclink, aws.vpc-endpoint, aws.redshift-subnet-group, aws.iam-profile, aws.transit-attachment, aws.rest-stage, aws.rest-api, aws.distribution, aws.cache-subnet-group, aws.ecs-service, aws.event-rule-target, aws.identity-pool, aws.ssm-activation, aws.rds-snapshot, aws.app-elb, aws.ecr, aws.peering-connection, aws.ebs, aws.config-rule, aws.dax, aws.kinesis, aws.rrset, aws.batch-compute, aws.kms, aws.cloudtrail, aws.dynamodb-backup, aws.dms-endpoint, aws.sqs, aws.sagemaker-endpoint, aws.gamelift-build, aws.shield-attack, aws.dms-instance, aws.backup-plan, aws.key-pair, aws.iot, aws.hostedzone, aws.log-group, aws.rds-subnet-group, aws.cache-cluster, aws.hsm, aws.vpn-gateway, aws.sagemaker-transform-job, aws.route-table, aws.dynamodb-stream, aws.redshift-snapshot, aws.efs-mount-target, aws.codecommit, aws.glacier, aws.elasticsearch, aws.event-rule, aws.ssm-parameter, aws.rds, aws.sagemaker-model, aws.account, aws.cloudhsm-cluster, aws.waf, aws.vpn-connection, aws.iam-certificate, aws.iam-user, aws.streaming-distribution, aws.ml-model, aws.network-acl, aws.health-event, aws.launch-config, aws.rds-cluster, aws.storage-gateway, aws.healthcheck, aws.opswork-cm, aws.opswork-stack, aws.user-pool, aws.acm-certificate, aws.datapipeline, aws.elb, aws.gamelift-fleet, aws.cloudsearch, aws.internet-gateway No implementation for event. Policies studied have 125 examples. .. code:: yaml name: ec2-using-key-pair-notify-new comment: Any EC2 instance that use a KeyName (key pair) will generate a notification resource: ec2 filters: - key: detail.userAgent op: not-equal type: event value: autoscaling.amazonaws.com - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - days: 1 op: less-than type: instance-age - key: KeyName type: value value: not-null actions: # REDACTED # .. code:: yaml name: ec2-using-key-pair-notify-new comment: Any EC2 instance that use a KeyName (key pair) will generate a notification resource: ec2 filters: - key: detail.userAgent op: not-equal type: event value: autoscaling.amazonaws.com - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - days: 1 op: less-than type: instance-age - key: KeyName type: value value: not-null actions: # REDACTED # .. code:: yaml name: ec2-using-key-pair-notify-new comment: Any EC2 instance that use a KeyName (key pair) will generate a notification resource: ec2 filters: - key: detail.userAgent op: not-equal type: event value: autoscaling.amazonaws.com - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - days: 1 op: less-than type: instance-age - key: KeyName type: value value: not-null actions: # REDACTED # The ``type: event`` filter examines data not directly part of a resource. A Lambda is changed by an event. This ``event`` detail is available in the activation along with the ``resource``. metrics ------- See `health-event`_ for a similar function. Schema .. code:: yaml attr-multiplier: {'type': 'number'} days: {'type': 'number'} dimensions: {'type': 'array', 'items': {'type': 'string'}} name: {'type': 'string'} namespace: {'type': 'string'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} percent-attr: {'type': 'string'} period: {'type': 'number'} statistics: {'type': 'string', 'enum': ['Average', 'Sum', 'Maximum', 'Minimum', 'SampleCount']} type: {'enum': ['metrics']} value: {'type': 'number'} Used by aws.log-group, aws.cache-cluster, aws.rds-param-group, aws.ecs, aws.firehose, aws.asg, aws.dynamodb-stream, aws.waf-regional, aws.dynamodb-table, aws.rest-api, aws.elasticsearch, aws.s3, aws.event-rule, aws.distribution, aws.message-broker, aws.redshift, aws.rds, aws.ecs-service, aws.waf, aws.rds-cluster-param-group, aws.app-elb, aws.lambda, aws.streaming-distribution, aws.ebs, aws.kinesis, aws.rds-cluster, aws.ec2, aws.dynamodb-backup, aws.opswork-stack, aws.sqs, aws.datapipeline, aws.emr, aws.elb, aws.cloudsearch, aws.sns Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 167 .. parsed-literal:: @filters.register(metrics) class AppElbMetrics Filter app load balancer by metric values. See available metrics here: https://goo.gl/TLQ9Fr Custodian defaults to specifying dimensions for the app elb only. Target Group dimension not supported atm. - In :file:`c7n/resources/elasticsearch.py` 105 .. parsed-literal:: @ElasticSearchDomain.filter_registry.register(metrics) class Metrics - In :file:`c7n/resources/emr.py` 123 .. parsed-literal:: @EMRCluster.filter_registry.register(metrics) class EMRMetrics - In :file:`c7n/resources/sqs.py` 99 .. parsed-literal:: @SQS.filter_registry.register(metrics) class MetricsFilter - In :file:`c7n/resources/cw.py` 97 .. parsed-literal:: @EventRule.filter_registry.register(metrics) class EventRuleMetrics - In :file:`c7n/resources/mq.py` 66 .. parsed-literal:: @MessageBroker.filter_registry.register(metrics) class MQMetrics - In :file:`c7n/resources/s3.py` 548 .. parsed-literal:: @filters.register(metrics) class S3Metrics S3 CW Metrics need special handling for attribute/dimension mismatch, and additional required dimension. - In :file:`c7n/resources/ecs.py` 69 .. parsed-literal:: @ECSCluster.filter_registry.register(metrics) class ECSMetrics - In :file:`c7n/resources/ecs.py` 182 .. parsed-literal:: @Service.filter_registry.register(metrics) class ServiceMetrics Policies studied have 111 examples. .. code:: yaml name: rds-unused-report description: Mark unused RDS instances that haven't had connections in 14 days resource: rds filters: - tag:custodian_cleanup: absent - ReadReplicaSourceDBInstanceIdentifier: absent - or: - and: - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - tag:OwnerEID: not-null - key: tag:OwnerEID op: not-equal type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (^[A-Za-z]{3}[0-9]{3}$) - key: InstanceCreateTime op: gt type: value value: 14 value_type: age - days: 14 name: DatabaseConnections op: equal type: metrics value: 0 actions: # REDACTED # .. code:: yaml name: rds-unused-report-no-owner description: Mark unused RDS instances that haven't had connections in 14 days resource: rds filters: - tag:custodian_cleanup: absent - ReadReplicaSourceDBInstanceIdentifier: absent - or: - tag:OwnerContact: absent - key: tag:OwnerContact op: eq type: value value: '' value_type: normalize - or: - tag:OwnerEID: absent - key: tag:OwnerEID op: eq type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (?!(^[A-Za-z]{3}[0-9]{3})$) - key: InstanceCreateTime op: gt type: value value: 14 value_type: age - days: 14 name: DatabaseConnections op: equal type: metrics value: 0 actions: # REDACTED # .. code:: yaml name: ec2-under-utilized-cpu-network-tag-radistis comment: Tag a resource with underutilized CPU and Network I/O In addition, last resize action should be >= 7 days and instance-age > 7 days. Runs at 2 PM EST everyday resource: ec2 filters: - default_tz: et offhour: 14 opt-out: true type: offhour - or: - tag:resize-backoff: absent - op: resize tag: resize-backoff type: marked-for-op - days: 7 op: gt type: instance-age - days: 7 name: CPUUtilization op: less-than period: 612000 statistics: Average type: metrics value: 10 - days: 7 name: CPUUtilization op: less-than period: 612000 statistics: Maximum type: metrics value: 20 - or: - days: 7 name: NetworkIn op: less-than period: 612000 statistics: Maximum type: metrics value: 2500000 - days: 7 name: NetworkOut op: less-than period: 612000 statistics: Maximum type: metrics value: 2500000 actions: # REDACTED # There are two parts to this. 1. Getting raw metric statistics from the cloud provider. The :py:func:`celpy.c7nlib.get_raw_metrics` is refactored from the ``Metrics`` filter into :py:func:`celpy.c7nlib.get_raw_metrics` function. 2. Getting metric statistics for a specific resource. The :py:func:`celpy.c7nlib.get_metrics` function takes parameters for period, start, end, and the statistics value to compute. The dimension comes from the Resource. This uses :py:func:`celpy.c7nlib.get_raw_metrics`. Generally, C7N requests in bunches of 50 per client connection. A worker pool processes the batches to keep from overwhelming AWS with metrics requests. See :py:class:`c7n.filters.metrics.MetricsFilter`. This filter collects metrics and applies the filter decision to items in each batch. The :py:meth:`process` and :py:meth:`process_resource_set` methods need to be refactored into several pieces: - :py:meth:`process_resource_set`. This is the existing interface. This calls :py:meth:`prepare_query` to create the various query parameters. It then creates a worker pool and applies :py:meth:`process_resource_set` to chunks of 50 resources. - :py:meth:`prepare_query`. This is new. It prepares the parameters for :py:meth:`client.get_metric_statistics`. - :py:meth:`process_resource_set`. This is the existing interface. It gets a client and then calls :py:meth:`get_resource_statistics` with the client and each resource. It calls :py:meth:`filter_resource_statistics` on the results of :py:meth:`client.get_metric_statistics`. - :py:meth:`get_resource_statistics`. Given a client and a resource, this function will set the resource's ``"c7n.metrics"`` attribute with current statistics. This is the ``['Datapoints']`` value. It returns the [self.statistics] item from each dictionary in the metrics list of dictionaries. - :py:meth:`filter_resource_statistics`. Given a resource, this function will apply the missing-value, the percent-attr and attr-multiplier transformations to the resource's ``"c7n.metrics"``. It will apply the filter op and value. All of these things better represented in CEL. This requires two extension functions: - :py:func:`c7nlib.get_raw_metrics` depends on :py:attr:`CELFilter.manager`. - :py:func:`c7nlib.get_metrics` depends on :py:func:`c7nlib.get_raw_metrics` age --- Schema .. code:: yaml days: {'type': 'number'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['age']} Used by aws.redshift-snapshot, aws.rds-snapshot, aws.rds-cluster-snapshot, aws.cache-snapshot, aws.launch-config, aws.ebs-snapshot Resource Type Implementations for {function.name}: - In :file:`c7n/resources/redshift.py` 643 .. parsed-literal:: @RedshiftSnapshot.filter_registry.register(age) class RedshiftSnapshotAge Filters redshift snapshots based on age (in days) :example: .. code-block:: yaml policies: - name: redshift-old-snapshots resource: redshift-snapshot filters: - type: age days: 21 op: gt - In :file:`c7n/resources/rds.py` 1045 .. parsed-literal:: @RDSSnapshot.filter_registry.register(age) class RDSSnapshotAge Filters RDS snapshots based on age (in days) :example: .. code-block:: yaml policies: - name: rds-snapshot-expired resource: rds-snapshot filters: - type: age days: 28 op: ge actions: - delete - In :file:`c7n/resources/elasticache.py` 325 .. parsed-literal:: @ElastiCacheSnapshot.filter_registry.register(age) class ElastiCacheSnapshotAge Filters elasticache snapshots based on their age (in days) :example: .. code-block:: yaml policies: - name: elasticache-stale-snapshots resource: cache-snapshot filters: - type: age days: 30 op: ge - In :file:`c7n/resources/rdscluster.py` 436 .. parsed-literal:: @RDSClusterSnapshot.filter_registry.register(age) class RDSSnapshotAge Filters rds cluster snapshots based on age (in days) :example: .. code-block:: yaml policies: - name: rds-cluster-snapshots-expired resource: rds-cluster-snapshot filters: - type: age days: 30 op: gt - In :file:`c7n/resources/asg.py` 1704 .. parsed-literal:: @LaunchConfig.filter_registry.register(age) class LaunchConfigAge Filter ASG launch configuration by age (in days) :example: .. code-block:: yaml policies: - name: asg-launch-config-old resource: launch-config filters: - type: age days: 90 op: ge - In :file:`c7n/resources/ebs.py` 154 .. parsed-literal:: @Snapshot.filter_registry.register(age) class SnapshotAge EBS Snapshot Age Filter Filters an EBS snapshot based on the age of the snapshot (in days) :example: .. code-block:: yaml policies: - name: ebs-snapshots-week-old resource: ebs-snapshot filters: - type: age days: 7 op: ge Policies studied have 101 examples. .. code:: yaml name: parent-ebs-snapshot-manual-mark comments: ebs manual snapshots older than 30 days will be marked and deleted in 7 days. resource: ebs-snapshot filters: - type: skip-ami-snapshots value: true - tag:custodian_snapshot: absent - tag:fs_manual_ebs_snapshot_expiring: absent - tag:exceptionmanualsnapshot: absent - key: VolumeId op: ne type: value value: vol-ffffffff - key: SnapshotId op: ni type: value value_from: expr: accounts."{account_id}".ebs.snapshots.*[][] format: json url: s3://redacted/bucket - key: SnapshotId op: ni type: value value_from: expr: exemptions.["ebs-snapshot"][].snapshot.["SnapshotId"][].*[].*[] format: json url: s3://redacted/bucket - days: 30 op: gte type: age actions: # REDACTED # .. code:: yaml name: parent-rds-snapshot-manual-mark comments: RDS manual snapshots older than 30 days will be marked and deleted in 7 days. resource: rds-snapshot filters: - tag:exceptionmanualsnapshot: absent - tag:fs_manual_rds_snapshot_expiring: absent - key: SnapshotType type: value value: manual - days: 30 op: gte type: age actions: # REDACTED # .. code:: yaml name: parent-launch-config-unused-gt-60-days description: Delete unused launch configurations. resource: launch-config filters: - days: 60 op: gt type: age - unused actions: # REDACTED # The ``type: age`` filter refers to an attribute with slightly varying names across resource types. The C7N DSL conceals these variations. There doesn't seem to be a good reason to conceal the slight variations in the attribute name. This leads to a number of variants, depending on the resource type - launch-config: ``Now - timestamp(Resource.CreatedTime) > duration("21d")`` - ebs-snapshot: ``Now - timestamp(Resource.StartTime) > duration("21d")`` - cache-snapshot: ``Now - timestamp(Resource.NodeSnaphots.min(x, x.SnapshotCreateTime)) > duration("21d")`` - rds-snapshot: ``Now - timestamp(Resource.SnapshotCreateTime) > duration("21d")`` - rds-cluster-snapshot: ``Now - timestamp(Resource.SnapshotCreateTime) > duration("21d")`` - redshift-snapshot: ``Now - timestamp(Resource.SnapshotCreateTime) > duration("21d")`` This requires one extension function: - :py:func:`c7nlib.image` which depends on :py:meth:`CELFilter.get_instance_image` security-group -------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} match-resource: {'type': 'boolean'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} operator: {'enum': ['and', 'or']} type: {'enum': ['security-group']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.cache-cluster, aws.codebuild, aws.asg, aws.vpc-endpoint, aws.eks, aws.efs-mount-target, aws.vpc, aws.elasticsearch, aws.message-broker, aws.redshift, aws.rds, aws.glue-connection, aws.sagemaker-notebook, aws.directory, aws.eni, aws.app-elb, aws.lambda, aws.dax, aws.rds-cluster, aws.batch-compute, aws.ec2, aws.elb, aws.dms-instance Resource Type Implementations for {function.name}: - In :file:`c7n/resources/redshift.py` 100 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/appelb.py` 184 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/vpc.py` 178 .. parsed-literal:: @Vpc.filter_registry.register(security-group) class VpcSecurityGroupFilter Filter VPCs based on Security Group attributes :example: .. code-block:: yaml policies: - name: gray-vpcs resource: vpc filters: - type: security-group key: tag:Color value: Gray - In :file:`c7n/resources/vpc.py` 1211 .. parsed-literal:: @NetworkInterface.filter_registry.register(security-group) class InterfaceSecurityGroupFilter Network interface security group filter :example: .. code-block:: yaml policies: - name: network-interface-ssh resource: eni filters: - type: security-group match-resource: true key: FromPort value: 22 - In :file:`c7n/resources/vpc.py` 1787 .. parsed-literal:: @VpcEndpoint.filter_registry.register(security-group) class EndpointSecurityGroupFilter - In :file:`c7n/resources/elasticsearch.py` 93 .. parsed-literal:: @ElasticSearchDomain.filter_registry.register(security-group) class SecurityGroup - In :file:`c7n/resources/rds.py` 293 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/elasticache.py` 80 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/dms.py` 128 .. parsed-literal:: @ReplicationInstance.filter_registry.register(security-group) class SecurityGroup - In :file:`c7n/resources/dynamodb.py` 429 .. parsed-literal:: @DynamoDbAccelerator.filter_registry.register(security-group) class DaxSecurityGroupFilter - In :file:`c7n/resources/rdscluster.py` 197 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/eks.py` 42 .. parsed-literal:: @EKS.filter_registry.register(security-group) class EKSSGFilter - In :file:`c7n/resources/batch.py` 37 .. parsed-literal:: @ComputeEnvironment.filter_registry.register(security-group) class ComputeSGFilter - In :file:`c7n/resources/code.py` 98 .. parsed-literal:: @CodeBuildProject.filter_registry.register(security-group) class BuildSecurityGroupFilter - In :file:`c7n/resources/glue.py` 47 .. parsed-literal:: @GlueConnection.filter_registry.register(security-group) class ConnectionSecurityGroupFilter - In :file:`c7n/resources/sagemaker.py` 622 .. parsed-literal:: @NotebookInstance.filter_registry.register(security-group) class NotebookSecurityGroupFilter - In :file:`c7n/resources/ec2.py` 173 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/mq.py` 60 .. parsed-literal:: @MessageBroker.filter_registry.register(security-group) class MQSGFilter - In :file:`c7n/resources/elb.py` 424 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter ELB security group filter - In :file:`c7n/resources/efs.py` 87 .. parsed-literal:: @ElasticFileSystemMountTarget.filter_registry.register(security-group) class SecurityGroup - In :file:`c7n/resources/directory.py` 58 .. parsed-literal:: @Directory.filter_registry.register(security-group) class DirectorySecurityGroupFilter - In :file:`c7n/resources/asg.py` 123 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter - In :file:`c7n/resources/awslambda.py` 115 .. parsed-literal:: @filters.register(security-group) class SecurityGroupFilter Policies studied have 48 examples. .. code:: yaml name: ec2-invalid-sg-delete-qa-east description: Find all EC2 instances that are using Testing-Only SG and remove hourly resource: ec2 filters: - key: GroupName op: regex type: security-group value: cml-testing-only-sg actions: # REDACTED # .. code:: yaml name: ec2-invalid-sg-delete-qa-west description: Find all EC2 instances that are using Testing-Only SG and remove hourly resource: ec2 filters: - key: GroupName op: regex type: security-group value: cml-testing-only-sg actions: # REDACTED # .. code:: yaml name: rds-invalid-sg-delete-qa-east description: Find all EC2 instances that are using Testing-Only SG and remove hourly resource: rds filters: - key: GroupName op: regex type: security-group value: cml-testing-only-sg actions: # REDACTED # The ``type: security-group`` filter looks at a related resource. This is similar to the way ``image-age`` looks at an associated resource. The linkage varies slightly among resource types. The :py:func:`celpy.c7nlib.security_group` and :py:func:`celpy.c7nlib.get_related_ids` functions fetch the related resource. This can then be examined to check group name, group id, or tags. This requires two extension functions: - :py:func:`c7nlib.get_related_ids` which depends on :py:meth:`CELFilter.get_related_ids` - :py:func:`c7nlib.security_group` which depends on :py:meth:`CELFilter.get_related` subnet ------ Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} match-resource: {'type': 'boolean'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} operator: {'enum': ['and', 'or']} type: {'enum': ['subnet']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.cache-cluster, aws.codebuild, aws.asg, aws.route-table, aws.vpc-endpoint, aws.eks, aws.efs-mount-target, aws.elasticsearch, aws.message-broker, aws.redshift, aws.rds, aws.glue-connection, aws.sagemaker-notebook, aws.directory, aws.eni, aws.app-elb, aws.lambda, aws.network-acl, aws.dax, aws.rds-cluster, aws.batch-compute, aws.ec2, aws.elb, aws.dms-instance Resource Type Implementations for {function.name}: - In :file:`c7n/resources/redshift.py` 106 .. parsed-literal:: @filters.register(subnet) class SubnetFilter - In :file:`c7n/resources/appelb.py` 190 .. parsed-literal:: @filters.register(subnet) class SubnetFilter - In :file:`c7n/resources/vpc.py` 1191 .. parsed-literal:: @NetworkInterface.filter_registry.register(subnet) class InterfaceSubnetFilter Network interface subnet filter :example: .. code-block:: yaml policies: - name: network-interface-in-subnet resource: eni filters: - type: subnet key: CidrBlock value: 10.0.2.0/24 - In :file:`c7n/resources/vpc.py` 1295 .. parsed-literal:: @RouteTable.filter_registry.register(subnet) class SubnetRoute Filter a route table by its associated subnet attributes. - In :file:`c7n/resources/vpc.py` 1493 .. parsed-literal:: @NetworkAcl.filter_registry.register(subnet) class AclSubnetFilter Filter network acls by the attributes of their attached subnets. :example: .. code-block:: yaml policies: - name: subnet-acl resource: network-acl filters: - type: subnet key: "tag:Location" value: Public - In :file:`c7n/resources/vpc.py` 1793 .. parsed-literal:: @VpcEndpoint.filter_registry.register(subnet) class EndpointSubnetFilter - In :file:`c7n/resources/elasticsearch.py` 87 .. parsed-literal:: @ElasticSearchDomain.filter_registry.register(subnet) class Subnet - In :file:`c7n/resources/rds.py` 299 .. parsed-literal:: @filters.register(subnet) class SubnetFilter - In :file:`c7n/resources/elasticache.py` 86 .. parsed-literal:: @filters.register(subnet) class SubnetFilter Filters elasticache clusters based on their associated subnet :example: .. code-block:: yaml policies: - name: elasticache-in-subnet-x resource: cache-cluster filters: - type: subnet key: SubnetId value: subnet-12ab34cd - In :file:`c7n/resources/dms.py` 122 .. parsed-literal:: @ReplicationInstance.filter_registry.register(subnet) class Subnet - In :file:`c7n/resources/dynamodb.py` 622 .. parsed-literal:: @DynamoDbAccelerator.filter_registry.register(subnet) class DaxSubnetFilter Filters DAX clusters based on their associated subnet group :example: .. code-block:: yaml policies: - name: dax-no-auto-public resource: dax filters: - type: subnet key: MapPublicIpOnLaunch value: False - In :file:`c7n/resources/rdscluster.py` 203 .. parsed-literal:: @filters.register(subnet) class SubnetFilter - In :file:`c7n/resources/eks.py` 36 .. parsed-literal:: @EKS.filter_registry.register(subnet) class EKSSubnetFilter - In :file:`c7n/resources/batch.py` 43 .. parsed-literal:: @ComputeEnvironment.filter_registry.register(subnet) class ComputeSubnetFilter - In :file:`c7n/resources/code.py` 92 .. parsed-literal:: @CodeBuildProject.filter_registry.register(subnet) class BuildSubnetFilter - In :file:`c7n/resources/glue.py` 41 .. parsed-literal:: @GlueConnection.filter_registry.register(subnet) class ConnectionSubnetFilter - In :file:`c7n/resources/sagemaker.py` 628 .. parsed-literal:: @NotebookInstance.filter_registry.register(subnet) class NotebookSubnetFilter - In :file:`c7n/resources/ec2.py` 179 .. parsed-literal:: @filters.register(subnet) class SubnetFilter - In :file:`c7n/resources/mq.py` 54 .. parsed-literal:: @MessageBroker.filter_registry.register(subnet) class MQSubnetFilter - In :file:`c7n/resources/elb.py` 431 .. parsed-literal:: @filters.register(subnet) class SubnetFilter ELB subnet filter - In :file:`c7n/resources/efs.py` 81 .. parsed-literal:: @ElasticFileSystemMountTarget.filter_registry.register(subnet) class Subnet - In :file:`c7n/resources/directory.py` 52 .. parsed-literal:: @Directory.filter_registry.register(subnet) class DirectorySubnetFilter - In :file:`c7n/resources/asg.py` 145 .. parsed-literal:: @filters.register(subnet) class SubnetFilter - In :file:`c7n/resources/awslambda.py` 121 .. parsed-literal:: @filters.register(subnet) class SubnetFilter Policies studied have 16 examples. .. code:: yaml name: ec2-restriction-az1e-notify-weekly resource: ec2 filters: - key: SubnetId op: in type: subnet value_from: format: txt url: s3://redacted/bucket value_type: normalize actions: # REDACTED # .. code:: yaml name: lambda-restriction-az1e-notify-weekly resource: lambda filters: - key: SubnetId op: in type: subnet value_from: format: txt url: s3://redacted/bucket value_type: normalize actions: # REDACTED # .. code:: yaml name: app-elb-restriction-az1e-notify-weekly resource: app-elb filters: - key: SubnetId op: in type: subnet value_from: format: txt url: s3://redacted/bucket value_type: normalize actions: # REDACTED # The ``type: subnet`` filter looks at a related resource. This is similar to the way ``security-group`` looks at an associated resource. The linkage varies slightly among resource types. See the :py:func:`celpy.c7nlib.subnet` function fetches the related resource. This can then be examined to check group name, group id, or tags. This requires one extension function: - :py:func:`c7nlib.subnet` which depends on :py:meth:`CELFilter.get_related`. flow-logs --------- Schema .. code:: yaml deliver-status: {'enum': ['success', 'failure']} destination: {'type': 'string'} destination-type: {'enum': ['s3', 'cloud-watch-logs']} enabled: {'type': 'boolean', 'default': False} log-group: {'type': 'string'} op: {'enum': ['equal', 'not-equal'], 'default': 'equal'} set-op: {'enum': ['or', 'and'], 'default': 'or'} status: {'enum': ['active']} traffic-type: {'enum': ['accept', 'reject', 'all']} type: {'enum': ['flow-logs']} Used by aws.vpc, aws.eni, aws.subnet Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 57 .. parsed-literal:: @Vpc.filter_registry.register(flow-logs) class FlowLogFilter Are flow logs enabled on the resource. ie to find all vpcs with flows logs disabled we can do this :example: .. code-block:: yaml policies: - name: flow-logs-enabled resource: vpc filters: - flow-logs or to find all vpcs with flow logs but that don't match a particular configuration. :example: .. code-block:: yaml policies: - name: flow-mis-configured resource: vpc filters: - not: - type: flow-logs enabled: true set-op: or op: equal # equality operator applies to following keys traffic-type: all status: active log-group: vpc-logs Policies studied have 9 examples. .. code:: yaml name: enterprise-enable-vpc-flow-logs comment: ISRM-78 All VPCs must have flow logs enabled resource: vpc filters: - enabled: false type: flow-logs actions: # REDACTED # .. code:: yaml name: OREO-vpc-CM6AWS11-NC description: ISRM 78 - VPC Flow Logs must be enable resource: vpc filters: - enabled: false type: flow-logs actions: # REDACTED # .. code:: yaml name: OREO-vpc-CM6AWS11-CBR description: ISRM 78 - VPC Flow Logs must be enable resource: vpc filters: - enabled: true type: flow-logs actions: # REDACTED # The ``type: flow-logs`` fklter looks at a related resource. This is similar to the way ``security-group`` and ``subnet`` work. This looks at an associated resource. The linkage varies slightly among resource types. See the :py:func:`celpy.c7nlib.flow_logs` function to fetch the related resource. This can then be examined to check group name, group id, or tags. This requires one extension function: - :py:func:`c7nlib.flow_logs` which depends on :py:meth:`CELFilter.get_flow_logs` tag-count --------- Schema .. code:: yaml count: {'type': 'integer', 'minimum': 0} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['tag-count']} Used by aws.hostedzone, aws.log-group, aws.cache-cluster, aws.efs, aws.vpn-gateway, aws.cache-snapshot, aws.asg, aws.route-table, aws.security-group, aws.vpc-endpoint, aws.kms-key, aws.vpc, aws.transit-attachment, aws.rest-stage, aws.glacier, aws.distribution, aws.network-addr, aws.ssm-parameter, aws.rds, aws.eni, aws.ebs-snapshot, aws.vpn-connection, aws.elasticbeanstalk-environment, aws.rds-snapshot, aws.app-elb, aws.customer-gateway, aws.streaming-distribution, aws.peering-connection, aws.network-acl, aws.ebs, aws.ami, aws.kinesis, aws.app-elb-target-group, aws.rds-cluster, aws.healthcheck, aws.subnet, aws.ec2, aws.nat-gateway, aws.elb, aws.transit-gateway, aws.internet-gateway, aws.key-pair No implementation for tag-count. Policies studied have 5 examples. .. code:: yaml name: ec2-tag-trim resource: ec2 filters: - tag:maid_status: absent - tag:cardda_tagcompliance: absent - tag:aws:autoscaling:groupName: absent - count: 50 type: tag-count actions: # REDACTED # .. code:: yaml name: rds-tag-trim resource: rds filters: - tag:cardda_tagcompliance: absent - or: - tag:ASV: absent - tag:CMDBEnvironment: absent - tag:OwnerContact: absent - tag:Project: absent - count: 10 type: tag-count actions: # REDACTED # .. code:: yaml name: ebs-tag-trim resource: ebs filters: - tag:maid_status: absent - count: 50 type: tag-count actions: # REDACTED # The ``type: tag-count`` filter doesn't require any extra functions. The filter generally translates to something like the following: ``size(Resource["Tags"].filter(x, ! matches(x.Key, "^aws:.*"))) >= 8`` vpc --- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} match-resource: {'type': 'boolean'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} operator: {'enum': ['and', 'or']} type: {'enum': ['vpc']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ec2, aws.eks, aws.app-elb, aws.lambda, aws.elb, aws.codebuild, aws.elasticsearch, aws.rds, aws.dms-instance, aws.directory, aws.eni, aws.vpc-endpoint Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 196 .. parsed-literal:: @filters.register(vpc) class VpcFilter - In :file:`c7n/resources/vpc.py` 1232 .. parsed-literal:: @NetworkInterface.filter_registry.register(vpc) class InterfaceVpcFilter - In :file:`c7n/resources/vpc.py` 1799 .. parsed-literal:: @VpcEndpoint.filter_registry.register(vpc) class EndpointVpcFilter - In :file:`c7n/resources/elasticsearch.py` 99 .. parsed-literal:: @ElasticSearchDomain.filter_registry.register(vpc) class Vpc - In :file:`c7n/resources/rds.py` 305 .. parsed-literal:: @filters.register(vpc) class VpcFilter - In :file:`c7n/resources/dms.py` 134 .. parsed-literal:: @ReplicationInstance.filter_registry.register(vpc) class Vpc - In :file:`c7n/resources/eks.py` 48 .. parsed-literal:: @EKS.filter_registry.register(vpc) class EKSVpcFilter - In :file:`c7n/resources/code.py` 104 .. parsed-literal:: @CodeBuildProject.filter_registry.register(vpc) class BuildVpcFilter - In :file:`c7n/resources/ec2.py` 185 .. parsed-literal:: @filters.register(vpc) class VpcFilter - In :file:`c7n/resources/elb.py` 438 .. parsed-literal:: @filters.register(vpc) class VpcFilter ELB vpc filter - In :file:`c7n/resources/directory.py` 64 .. parsed-literal:: @Directory.filter_registry.register(vpc) class DirectoryVpcFilter - In :file:`c7n/resources/awslambda.py` 127 .. parsed-literal:: @filters.register(vpc) class VpcFilter Policies studied have 4 examples. .. code:: yaml name: ec2-offhours-tagging resource: ec2 filters: - State.Name: running - tag:aws:autoscaling:groupName: absent - tag:aws:elasticmapreduce:job-flow-id: absent - tag:aws:elasticmapreduce:instance-group-role: absent - tag:Component: absent - key: VpcId op: not-in type: vpc value_from: expr: not_null(offhours_exceptions."{account_id}"."account", '[]') format: json url: s3://redacted/bucket - or: - tag:custodian_downtime: absent - key: tag:custodian_downtime op: in type: value value: - 'off' - 'False' - key: tag:custodian_downtime op: eq type: value value: false actions: # REDACTED # .. code:: yaml name: ec2-offhours-component-tagging resource: ec2 filters: - State.Name: running - tag:aws:autoscaling:groupName: absent - tag:aws:elasticmapreduce:job-flow-id: absent - tag:aws:elasticmapreduce:instance-group-role: absent - tag:Component: present - key: VpcId op: not-in type: vpc value_from: expr: not_null(offhours_exceptions."{account_id}"."account", '[]') format: json url: s3://redacted/bucket - key: tag:Component op: not-in type: value value_from: expr: not_null(offhours_exceptions."{account_id}"."account", '[]') format: json url: s3://redacted/bucket - or: - tag:custodian_downtime: absent - key: tag:custodian_downtime op: in type: value value: - 'off' - 'False' - key: tag:custodian_downtime op: eq type: value value: false actions: # REDACTED # .. code:: yaml name: rds-offhours-tagging resource: rds filters: - ReadReplicaDBInstanceIdentifiers: empty - ReadReplicaSourceDBInstanceIdentifier: empty - DBClusterIdentifier: absent - tag:Component: absent - tag:custodian_rds_offhours_et: absent - tag:custodian_rds_offhours_ct: absent - tag:custodian_rds_offhours_pt: absent - key: VpcId op: not-in type: vpc value_from: expr: not_null(offhours_exceptions."{account_id}"."account", '[]') format: json url: s3://redacted/bucket - not: - key: Engine op: contains type: value value: aurora actions: # REDACTED # The ``type: vpc`` filter looks at a related resource. This is similar to the way ``security-group`` and ``subnet`` work. This looks at an associated resource. The linkage varies slightly among resource types. See the :py:func:`celpy.c7nlib.vpc` function to fetch the related resource. This can then be examined to check group name, group id, or tags. This requires one extension function: - :py:func:`c7nlib.vpc` which depends on :py:meth:`CELFilter.get_related` credential ---------- Schema .. code:: yaml key: {'type': 'string', 'title': 'report key to search', 'enum': ['user', 'arn', 'user_creation_time', 'password_enabled', 'password_last_used', 'password_last_changed', 'password_next_rotation', 'mfa_active', 'access_keys', 'access_keys.active', 'access_keys.last_used_date', 'access_keys.last_used_region', 'access_keys.last_used_service', 'access_keys.last_rotated', 'certs', 'certs.active', 'certs.last_rotated']} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} report_delay: {'title': 'Number of seconds to wait for report generation.', 'default': 10, 'type': 'number'} report_generate: {'title': 'Generate a report if none is present.', 'default': True, 'type': 'boolean'} report_max_age: {'title': 'Number of seconds to consider a report valid.', 'default': 86400, 'type': 'number'} type: {'enum': ['credential']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.account, aws.iam-user Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 987 .. parsed-literal:: @User.filter_registry.register(credential) class UserCredentialReport - In :file:`c7n/resources/account.py` 81 .. parsed-literal:: @filters.register(credential) class AccountCredentialReport Policies studied have 2 examples. .. code:: yaml name: iam-active-key-lastrotate-notify comments: Check and notify resource owner of active keys not rotated in last 55 days. Keys will need to be rotated every 60 days. resource: iam-user filters: - key: access_keys.active type: credential value: true - key: access_keys.last_rotated op: gte type: credential value: 55 value_type: age actions: # REDACTED # .. code:: yaml name: iam-active-key-lastrotate-notify comments: Check and notify resource owner of active keys not rotated in last 55 days. Keys will need to be rotated every 60 days. resource: iam-user filters: - key: access_keys.active type: credential value: true - key: access_keys.last_rotated op: gte type: credential value: 55 value_type: age actions: # REDACTED # There are two examples of ``type: credential`` filters. These look at the credentials associated with IAM roles. See the :py:func:`celpy.c7nlib.credentials` function to fetch the related resource. This requires two extension functions: - :py:func:`c7nlib.subst` - :py:func:`c7nlib.credentials` which depends on :py:meth:`CELFilter.get_credential_report` image ----- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['image']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ec2, aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 431 .. parsed-literal:: @filters.register(image) class InstanceImage - In :file:`c7n/resources/asg.py` 608 .. parsed-literal:: @filters.register(image) class ImageFilter Filter asg by image :example: .. code-block:: yaml policies: - name: non-windows-asg resource: asg filters: - type: image key: Platform value: Windows op: ne Policies studied have 2 examples. .. code:: yaml name: parent-ec2-ancient-images-notify-warn comment: Identify EC2 instances that configured with AMIs older than 25 days resource: ec2 filters: - tag:proxy: absent - tag:aws:autoscaling:groupName: absent - days: 25 op: gte type: image-age - days: 30 op: lt type: image-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - key: Name op: regex type: image value: (?!WIN.*) actions: # REDACTED # .. code:: yaml name: parent-ec2-ancient-images-notify comment: Identify EC2 instances that configured with AMIs older than 30 days resource: ec2 filters: - tag:proxy: absent - tag:aws:autoscaling:groupName: absent - days: 30 op: gte type: image-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - key: Name op: regex type: image value: (?!WIN.*) actions: # REDACTED # Like the ``type: image-age``, the ``type: image`` filter looks at the related Image resource. See the :py:func:`celpy.c7nlib.image` function to fetch the related resource, the ImageName and CreationDate are available in the related resource. Note the complex regex: ``(?!WIN.*)``. This does not translated trivially to CEL: a manual revision to this filter is strongly suggested, something like this: ``! Resource.image().Name.matches("WIN.*")`` kms-alias --------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['kms-alias']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ebs, aws.rds Resource Type Implementations for {function.name}: - In :file:`c7n/resources/rds.py` 314 .. parsed-literal:: @filters.register(kms-alias) class KmsKeyAlias - In :file:`c7n/resources/ebs.py` 549 .. parsed-literal:: @filters.register(kms-alias) class KmsKeyAlias Policies studied have 2 examples. .. code:: yaml name: ebs-no-kms-keys comment: Detect all EBS volumes EBS volumes not encrypted with customer managed key resource: ebs filters: - key: AliasName op: regex type: kms-alias value: ^(alias/aws/) actions: # REDACTED # .. code:: yaml name: rds-no-kms-keys comment: Detect all RDS databases not encrypted with customer managed key resource: rds filters: - key: AliasName op: regex type: kms-alias value: ^(alias/aws/) actions: # REDACTED # The ``type: kms-alias`` filter looks at related information. See the :py:func:`celpy.c7nlib.kms_alias` function to fetch the related resource This requires one extension function: - :py:func:`c7nlib.kms_alias` which depends on :py:meth:`CELFilter.get_matching_aliases`. kms-key ------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} match-resource: {'type': 'boolean'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} operator: {'enum': ['and', 'or']} type: {'enum': ['kms-key']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.sns, aws.dynamodb-table, aws.dms-instance Resource Type Implementations for {function.name}: - In :file:`c7n/resources/dms.py` 116 .. parsed-literal:: @ReplicationInstance.filter_registry.register(kms-key) class KmsFilter - In :file:`c7n/resources/dynamodb.py` 98 .. parsed-literal:: @Table.filter_registry.register(kms-key) class KmsFilter Filter a resource by its associcated kms key and optionally the aliasname of the kms key by using 'c7n:AliasName' :example: .. code-block:: yaml policies: - name: dynamodb-kms-key-filters resource: dynamodb-table filters: - type: kms-key key: c7n:AliasName value: "^(alias/aws/dynamodb)" op: regex - In :file:`c7n/resources/sns.py` 257 .. parsed-literal:: @SNS.filter_registry.register(kms-key) class KmsFilter Policies studied have 1 examples. .. code:: yaml name: enterprise-dynamodb-table-app-kms-key-unmark description: SC-28.AWS.16 - DynamoDB Tables in CDE must be encrypted with a enterprise key or an app specific KMS key resource: dynamodb-table filters: - key: c7n:AliasName op: regex type: kms-key value: ^(alias/enterprise) - 'tag: enterprise-controls-SC-28.AWS.16': not-null actions: # REDACTED # The ``type: kms-alias`` filter looks at related information. See the :py:func:`celpy.c7nlib.kms_key` function to fetch the related resource This requires one extension function: - :py:func:`c7nlib.kms_key` which depends on :py:meth:`CELFilter.get_related` config-compliance (no examples) ------------------------------- Schema .. code:: yaml eval_filters: {'type': 'array', 'items': {'oneOf': [{'$ref': '#/definitions/filters/valuekv'}, {'$ref': '#/definitions/filters/value'}]}} op: {'enum': ['or', 'and']} rules: {'type': 'array', 'items': {'type': 'string'}} states: {'type': 'array', 'items': {'enum': ['COMPLIANT', 'NON_COMPLIANT', 'NOT_APPLICABLE', 'INSUFFICIENT_DATA']}} type: {'enum': ['config-compliance']} Used by aws.iam-policy, aws.iam-group, aws.codebuild, aws.vpn-gateway, aws.asg, aws.security-group, aws.redshift-snapshot, aws.waf-regional, aws.redshift-subnet-group, aws.dynamodb-table, aws.vpc, aws.s3, aws.rds-subscription, aws.distribution, aws.network-addr, aws.redshift, aws.rds, aws.eni, aws.waf, aws.vpn-connection, aws.rds-snapshot, aws.app-elb, aws.iam-user, aws.lambda, aws.streaming-distribution, aws.alarm, aws.network-acl, aws.ebs, aws.dax, aws.launch-config, aws.subnet, aws.ec2, aws.cloudtrail, aws.dynamodb-backup, aws.cfn, aws.acm-certificate, aws.elb, aws.iam-role, aws.internet-gateway No implementation for config-compliance. Policies studied have 0 examples. user-data (no examples) ----------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['user-data']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ec2, aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 676 .. parsed-literal:: @filters.register(user-data) class UserData Filter on EC2 instances which have matching userdata. Note: It is highly recommended to use regexes with the ?sm flags, since Custodian uses re.match() and userdata spans multiple lines. :example: .. code-block:: yaml policies: - name: ec2_userdata_stop resource: ec2 filters: - type: user-data op: regex value: (?smi).*password= actions: - stop - In :file:`c7n/resources/asg.py` 829 .. parsed-literal:: @filters.register(user-data) class UserDataFilter Filter on ASG's whose launch configs have matching userdata. Note: It is highly recommended to use regexes with the ?sm flags, since Custodian uses re.match() and userdata spans multiple lines. :example: .. code-block:: yaml policies: - name: lc_userdata resource: asg filters: - type: user-data op: regex value: (?smi).*password= actions: - delete Policies studied have 0 examples. shield-metrics (no examples) ---------------------------- Schema .. code:: yaml attr-multiplier: {'type': 'number'} days: {'type': 'number'} dimensions: {'type': 'array', 'items': {'type': 'string'}} name: {'type': 'string'} namespace: {'type': 'string'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} percent-attr: {'type': 'string'} period: {'type': 'number'} statistics: {'type': 'string', 'enum': ['Average', 'Sum', 'Maximum', 'Minimum', 'SampleCount']} type: {'enum': ['shield-metrics']} value: {'type': 'number'} Used by aws.elb, aws.distribution No implementation for shield-metrics. Policies studied have 0 examples. status (no examples) -------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['status']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.config-rule, aws.cloudtrail Resource Type Implementations for {function.name}: - In :file:`c7n/resources/cloudtrail.py` 74 .. parsed-literal:: @CloudTrail.filter_registry.register(status) class Status Filter a cloudtrail by its status. :Example: .. code-block:: yaml policies: - name: cloudtrail-not-active resource: aws.cloudtrail filters: - type: status key: IsLogging value: False - In :file:`c7n/resources/config.py` 35 .. parsed-literal:: @ConfigRule.filter_registry.register(status) class RuleStatus Policies studied have 0 examples. instance (no examples) ---------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['instance']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ebs, aws.elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/elb.py` 448 .. parsed-literal:: @filters.register(instance) class Instance Filter ELB by an associated instance value(s) :example: .. code-block:: yaml policies: - name: elb-image-filter resource: elb filters: - type: instance key: ImageId value: ami-01ab23cd - In :file:`c7n/resources/ebs.py` 505 .. parsed-literal:: @filters.register(instance) class AttachedInstanceFilter Filter volumes based on filtering on their attached instance :example: .. code-block:: yaml policies: - name: instance-ebs-volumes resource: ebs filters: - instance Policies studied have 0 examples. task-definition (no examples) ----------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['task-definition']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ecs-task, aws.ecs-service Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ecs.py` 223 .. parsed-literal:: @Service.filter_registry.register(task-definition) class ServiceTaskDefinitionFilter Filter services by their task definitions. :Example: Find any fargate services that are running with a particular image in the task and delete them. .. code-block:: yaml policies: - name: fargate-readonly-tasks resource: ecs-task filters: - launchType: FARGATE - type: task-definition key: "containerDefinitions[].image" value: "elasticsearch/elasticsearch:6.4.3 value_type: swap op: contains actions: - delete - In :file:`c7n/resources/ecs.py` 317 .. parsed-literal:: @Task.filter_registry.register(task-definition) class TaskTaskDefinitionFilter Filter tasks by their task definition. :Example: Find any fargate tasks that are running without read only root and stop them. .. code-block:: yaml policies: - name: fargate-readonly-tasks resource: ecs-task filters: - launchType: FARGATE - type: task-definition key: "containerDefinitions[].readonlyRootFilesystem" value: None value_type: swap op: contains actions: - stop Policies studied have 0 examples. Common/Boolean Filters ====================== These are functions that examine and make a decision, providing a boolean result. Because no explicit ``op:`` is provided in C7N, we must examine the semantics of each individual DSL construct to map it to both a source of data, and a CEL operator. In principle, this leads us to a function to extract data from the C7N resource description, in a form that CEL can use. The operation should be exposed instead of implied. offhour ------- Schema .. code:: yaml default_tz: {'type': 'string'} offhour: {'type': 'integer', 'minimum': 0, 'maximum': 23} opt-out: {'type': 'boolean'} skip-days: {'type': 'array', 'items': {'type': 'string', 'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}'}} skip-days-from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} tag: {'type': 'string'} type: {'enum': ['offhour']} weekends: {'type': 'boolean'} weekends-only: {'type': 'boolean'} Used by aws.ec2, aws.asg, aws.rds Resource Type Implementations for {function.name}: - In :file:`c7n/resources/rds.py` 262 .. parsed-literal:: @filters.register(offhour) class RDSOffHour Scheduled action on rds instance. - In :file:`c7n/resources/ec2.py` 455 .. parsed-literal:: @filters.register(offhour) class InstanceOffHour Custodian OffHour filter Filters running EC2 instances with the intent to stop at a given hour of the day. A list of days to excluded can be included as a list of strings with the format YYYY-MM-DD. Alternatively, the list (using the same syntax) can be taken from a specified url. :Example: .. code-block:: yaml policies: - name: offhour-evening-stop resource: ec2 filters: - type: offhour tag: custodian_downtime default_tz: et offhour: 20 actions: - stop - name: offhour-evening-stop-skip-holidays resource: ec2 filters: - type: offhour tag: custodian_downtime default_tz: et offhour: 20 skip-days: ['2017-12-25'] actions: - stop - name: offhour-evening-stop-skip-holidays-from resource: ec2 filters: - type: offhour tag: custodian_downtime default_tz: et offhour: 20 skip-days-from: expr: 0 format: csv url: 's3://location/holidays.csv' actions: - stop Policies studied have 125 examples. .. code:: yaml name: parent-asg-offhours-8x5-suspend resource: asg filters: - or: - tag:custodian_resize: absent - tag:resize_config: absent - key: SuspendedProcesses op: equal type: value value: [] - key: tag:Uptime op: in type: value value: - 08-19-weekend-off - 8x5 value_type: normalize - default_tz: ct offhour: 19 opt-out: true type: offhour actions: # REDACTED # .. code:: yaml name: parent-asg-offhours-24x5-suspend resource: asg filters: - or: - tag:custodian_resize: absent - tag:resize_config: absent - key: SuspendedProcesses op: equal type: value value: [] - key: tag:Uptime op: in type: value value: - down-weekends - 24x5 value_type: normalize - default_tz: ct offhour: 19 opt-out: true type: offhour weekends-only: true actions: # REDACTED # .. code:: yaml name: parent-asg-offhours-custom-suspend resource: asg filters: - or: - tag:custodian_resize: absent - tag:resize_config: absent - key: SuspendedProcesses op: equal type: value value: [] - key: tag:Uptime op: in type: value value: - custom value_type: normalize - default_tz: ct offhour: 19 tag: custodian_downtime type: offhour actions: # REDACTED # An Offhour (as well as an Onhour) filter is used to compare the current time against a scheduled on or off time. These policies are focused very narrowly on the current time. These policies are evaluated hourly; during each run (once an hour), cloud-custodian will act on **only** the resources tagged for that **exact** hour. In CEL, the common case is ``getHours(Now) == 19``, where the policy had ``offhour: 19``. C7N has the following features and CEL implentations. - **weekends**: default true, whether to leave resources off for the weekend, i.e., do nothing on the weekend. In effect, silence the filter on weekends. CEL: ``! getDayOfWeek(Now) in [0, 6]`` - **weekend-only**: default false, whether to turn the resource off only on, i.e., take action only on the weekend. In effect, silence the filter on weekdays. CEL: ``getDayOfWeek(Now) in [0, 6]`` - **default_tz**: which timezone to utilize when evaluating time **(REQUIRED)** The timezone is a second parameter to the extraction function. CEL: ``Now.getDayOfWeek("PST")`` applies PST before extracting the day-of-week value. - **tag**: which resource tag name to use for per-resource configuration (schedule and timezone overrides and opt-in/opt-out); default is ``maid_offhours``. This is troublingly difficult because the tag's syntax implies a CEL expression that becomes invisible. CEL: ``key_value("maid_offhours").resource_schedule(Now)`` - **opt-out**: Determines the behavior for resources which do not have a tag matching the one specified for **tag**. Values can be either ``false`` (the default) where the policy operates on an opt-in basis and resources must have the tag in order to be acted on by the policy, or ``true`` where the policy operates on an opt-out basis, and resources without the tag are acted on by the policy. CEL for ``opt-out: false``: ``Resource.Tags.exists(x, x.key=="maid_offhours") ? key_value("maid_offhours").resource_schedule(Now) || (other rules) : false``. CEL for ``opt-out: true``: ``Resource.Tags.exists(x, x.key=="maid_offhours") ? false : (other rules)``. - **onhour**: the default time to start/run resources, specified as 0-23. CEL: ``Now.getHour() == onhour``. - **offhour**: the default time to stop/suspend resources, specified as 0-23. CEL: ``Now.getHour() == offhour``. - **skip-days**: a list of dates to skip. Dates must use format YYYY-MM-DD. CEL: ``! getDate(Now) in ["YYYY-MM-DD"].map(d, getDate(timestamp(d)))`` - **skip-days-from**: a list of dates to skip stored at a url. **expr**, **format**, and **url** must be passed as parameters. Same syntax as ``value_from``. Can not specify both **skip-days-from** and **skip-days**. CEL: ``! getDate(Now) in value_from("url").jmes_path("date").map(d, getDate(timestamp(d)))`` The ``resource_schedule()`` function uses the C7N schedule sublanguage for a specific resource. This describes the on-hour and off-hour processing for a single resource. Here is the special tag value syntax. A semicolon-separated string composed of one or more of the following components, which override the defaults specified in the policy: * ``tz=`` to evaluate with a resource-specific timezone, where ```` is either one of the supported timezone aliases defined in :py:attr:`c7n.filters.offhours.Time.TZ_ALIASES` (such as ``pt``) or the name of a geographic timezone identifier in [IANA's tzinfo database](https://www.iana.org/time-zones), such as ``Americas/Los_Angeles``. *(Note all timezone aliases are referenced to a locality to ensure taking into account local daylight savings time, if applicable.)* * ``off=(time spec)`` and/or ``on=(time spec)`` matching time specifications supported by :py:class:`c7n.filters.offhours.ScheduleParser` as described in the next section. Each time specification follows the format ``(days,hours)``. Multiple time specifications can be combined in square-bracketed lists, i.e. ``[(days,hours),(days,hours),(days,hours)]``. Days are M, T, W, H, F, S, U. **Examples**:: # up mon-fri from 7am-7pm; eastern time off=(M-F,19);on=(M-F,7) # up mon-fri from 6am-9pm; up sun from 10am-6pm; pacific time off=[(M-F,21),(U,18)];on=[(M-F,6),(U,10)];tz=pt The :py:func:`resource_schedule` function reaches into the :py:class:`c7n.filters.offhours.ScheduleParser` class to parse the schedule text and compare it against the current day and hour in the given ``Now`` value. An alternative is to eschew this special language and replace it with CEL. These are *long* tag values, making this unwieldy. - ``{"off": Now.getDayOfWeek() in [1,2,3,4,5] && Now.getHour() == 19, "on": Now.getDayOfWeek() in [1,2,3,4,5] && Now.getHour() == 7}``. - ``{"off": (Now.getDayOfWeek("PT") in [1,2,3,4,5] && Now.getHour() == 21) || (Now.getDayOfWeek("PT") == 0 && Now.getHour() == 18), "on": (Now.getDayOfWeek("PT") in [1,2,3,4,5] && Now.getHour() == 6) || (Now.getDayOfWeek("PT") == 0 && Now.getHour() == 10)}``. The terse tag language should probably be left in place. This requires one extension function: - :py:func:`c7nlib.resource_schedule` which depends on :py:meth:`CELFilter.parser.parse` onhour ------ See offhour_. Schema .. code:: yaml default_tz: {'type': 'string'} onhour: {'type': 'integer', 'minimum': 0, 'maximum': 23} opt-out: {'type': 'boolean'} skip-days: {'type': 'array', 'items': {'type': 'string', 'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}'}} skip-days-from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} tag: {'type': 'string'} type: {'enum': ['onhour']} weekends: {'type': 'boolean'} weekends-only: {'type': 'boolean'} Used by aws.ec2, aws.asg, aws.rds, aws.rds-snapshot Resource Type Implementations for {function.name}: - In :file:`c7n/resources/rds.py` 268 .. parsed-literal:: @filters.register(onhour) class RDSOnHour Scheduled action on rds instance. - In :file:`c7n/resources/rds.py` 1021 .. parsed-literal:: @RDSSnapshot.filter_registry.register(onhour) class RDSSnapshotOnHour Scheduled action on rds snapshot. - In :file:`c7n/resources/ec2.py` 512 .. parsed-literal:: @filters.register(onhour) class InstanceOnHour Custodian OnHour filter Filters stopped EC2 instances with the intent to start at a given hour of the day. A list of days to excluded can be included as a list of strings with the format YYYY-MM-DD. Alternatively, the list (using the same syntax) can be taken from a specified url. :Example: .. code-block:: yaml policies: - name: onhour-morning-start resource: ec2 filters: - type: onhour tag: custodian_downtime default_tz: et onhour: 6 actions: - start - name: onhour-morning-start-skip-holidays resource: ec2 filters: - type: onhour tag: custodian_downtime default_tz: et onhour: 6 skip-days: ['2017-12-25'] actions: - start - name: onhour-morning-start-skip-holidays-from resource: ec2 filters: - type: onhour tag: custodian_downtime default_tz: et onhour: 6 skip-days-from: expr: 0 format: csv url: 's3://location/holidays.csv' actions: - start Policies studied have 88 examples. .. code:: yaml name: parent-asg-onhours-8x5-resume resource: asg filters: - tag:custodian_stopped: not-null - key: tag:Uptime op: in type: value value: - 08-19-weekend-off - 8x5 value_type: normalize - default_tz: ct onhour: 8 opt-out: true skip-days: - '2019-11-28' - '2019-11-29' - '2019-12-25' - '2020-01-01' - '2020-01-20' - '2020-02-17' - '2020-05-25' - '2020-07-03' - '2020-10-12' - '2020-11-11' - '2020-11-26' - '2020-11-27' - '2020-12-25' - '2021-01-01' type: onhour actions: # REDACTED # .. code:: yaml name: parent-asg-onhours-24x5-resume resource: asg filters: - tag:custodian_stopped: not-null - key: tag:Uptime op: in type: value value: - down-weekends - 24x5 value_type: normalize - default_tz: ct onhour: 8 opt-out: true skip-days: - '2019-11-28' - '2019-11-29' - '2019-12-25' - '2020-01-01' - '2020-01-20' - '2020-02-17' - '2020-05-25' - '2020-07-03' - '2020-10-12' - '2020-11-11' - '2020-11-26' - '2020-11-27' - '2020-12-25' - '2021-01-01' type: onhour weekends-only: true actions: # REDACTED # .. code:: yaml name: parent-asg-onhours-custom-resume resource: asg filters: - tag:custodian_stopped: not-null - key: tag:Uptime op: in type: value value: - custom value_type: normalize - default_tz: ct onhour: 8 skip-days: - '2019-11-28' - '2019-11-29' - '2019-12-25' - '2020-01-01' - '2020-01-20' - '2020-02-17' - '2020-05-25' - '2020-07-03' - '2020-10-12' - '2020-11-11' - '2020-11-26' - '2020-11-27' - '2020-12-25' - '2021-01-01' tag: custodian_downtime type: onhour actions: # REDACTED # cross-account ------------- Schema .. code:: yaml actions: {'type': 'array', 'items': {'type': 'string'}} everyone_only: {'type': 'boolean'} type: {'enum': ['cross-account']} whitelist: {'type': 'array', 'items': {'type': 'string'}} whitelist_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} whitelist_conditions: {'type': 'array', 'items': {'type': 'string'}} whitelist_endpoints: {'type': 'array', 'items': {'type': 'string'}} whitelist_endpoints_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} whitelist_orgids: {'type': 'array', 'items': {'type': 'string'}} whitelist_orgids_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} whitelist_protocols: {'type': 'array', 'items': {'type': 'string', 'enum': ['http', 'https', 'email', 'email-json', 'sms', 'sqs', 'application', 'lambda']}} whitelist_protocols_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} whitelist_vpc: {'type': 'array', 'items': {'type': 'string'}} whitelist_vpc_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} whitelist_vpce: {'type': 'array', 'items': {'type': 'string'}} whitelist_vpce_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} Used by aws.log-group, aws.vpc-endpoint, aws.redshift-snapshot, aws.kms-key, aws.glacier, aws.rest-api, aws.s3, aws.ebs-snapshot, aws.event-rule-target, aws.rds-snapshot, aws.lambda, aws.ecr, aws.peering-connection, aws.ami, aws.lambda-layer, aws.kms, aws.sqs, aws.sns, aws.iam-role Resource Type Implementations for {function.name}: - In :file:`c7n/resources/redshift.py` 667 .. parsed-literal:: @RedshiftSnapshot.filter_registry.register(cross-account) class RedshiftSnapshotCrossAccount Filter all accounts that allow access to non-whitelisted accounts - In :file:`c7n/resources/vpc.py` 1410 .. parsed-literal:: @PeeringConnection.filter_registry.register(cross-account) class CrossAccountPeer - In :file:`c7n/resources/vpc.py` 1779 .. parsed-literal:: @VpcEndpoint.filter_registry.register(cross-account) class EndpointCrossAccountFilter - In :file:`c7n/resources/rds.py` 1180 .. parsed-literal:: @RDSSnapshot.filter_registry.register(cross-account) class CrossAccountAccess - In :file:`c7n/resources/iam.py` 400 .. parsed-literal:: @Role.filter_registry.register(cross-account) class RoleCrossAccountAccess - In :file:`c7n/resources/sqs.py` 108 .. parsed-literal:: @SQS.filter_registry.register(cross-account) class SQSCrossAccount Filter SQS queues which have cross account permissions :example: .. code-block:: yaml policies: - name: sqs-cross-account resource: sqs filters: - type: cross-account - In :file:`c7n/resources/glacier.py` 58 .. parsed-literal:: @Glacier.filter_registry.register(cross-account) class GlacierCrossAccountAccessFilter Filter to return all glacier vaults with cross account access permissions The whitelist parameter will omit the accounts that match from the return :example: .. code-block:: yaml policies: - name: glacier-cross-account resource: glacier filters: - type: cross-account whitelist: - permitted-account-01 - permitted-account-02 - In :file:`c7n/resources/ami.py` 257 .. parsed-literal:: @filters.register(cross-account) class AmiCrossAccountFilter - In :file:`c7n/resources/apigw.py` 128 .. parsed-literal:: @RestApi.filter_registry.register(cross-account) class RestApiCrossAccount - In :file:`c7n/resources/cw.py` 117 .. parsed-literal:: @EventRuleTarget.filter_registry.register(cross-account) class CrossAccountFilter - In :file:`c7n/resources/cw.py` 277 .. parsed-literal:: @LogGroup.filter_registry.register(cross-account) class LogCrossAccountFilter - In :file:`c7n/resources/ecr.py` 43 .. parsed-literal:: @ECR.filter_registry.register(cross-account) class ECRCrossAccountAccessFilter Filters all EC2 Container Registries (ECR) with cross-account access :example: .. code-block:: yaml policies: - name: ecr-cross-account resource: ecr filters: - type: cross-account whitelist_from: expr: "accounts.*.accountNumber" url: *accounts_url - In :file:`c7n/resources/s3.py` 562 .. parsed-literal:: @filters.register(cross-account) class S3CrossAccountFilter Filters cross-account access to S3 buckets :example: .. code-block:: yaml policies: - name: s3-acl resource: s3 region: us-east-1 filters: - type: cross-account - In :file:`c7n/resources/awslambda.py` 238 .. parsed-literal:: @filters.register(cross-account) class LambdaCrossAccountAccessFilter Filters lambda functions with cross-account permissions The whitelist parameter can be used to prevent certain accounts from being included in the results (essentially stating that these accounts permissions are allowed to exist) This can be useful when combining this filter with the delete action. :example: .. code-block:: yaml policies: - name: lambda-cross-account resource: lambda filters: - type: cross-account whitelist: - 'IAM-Policy-Cross-Account-Access' - In :file:`c7n/resources/awslambda.py` 569 .. parsed-literal:: @LambdaLayerVersion.filter_registry.register(cross-account) class LayerCrossAccount - In :file:`c7n/resources/sns.py` 80 .. parsed-literal:: @SNS.filter_registry.register(cross-account) class SNSCrossAccount Filter to return all SNS topics with cross account access permissions The whitelist parameter will omit the accounts that match from the return :example: .. code-block:: yaml policies: - name: sns-cross-account resource: sns filters: - type: cross-account whitelist: - permitted-account-01 - permitted-account-02 - In :file:`c7n/resources/ebs.py` 198 .. parsed-literal:: @Snapshot.filter_registry.register(cross-account) class SnapshotCrossAccountAccess Policies studied have 86 examples. .. code:: yaml name: sns-cross-account-notify resource: sns filters: - type: cross-account whitelist_from: expr: accounts.*.account url: https://redacted/path actions: # REDACTED # .. code:: yaml name: sqs-cross-account-notify resource: sqs filters: - type: cross-account whitelist_from: expr: accounts.*.account url: https://redacted/path actions: # REDACTED # .. code:: yaml name: lambda-cross-account-notify resource: lambda filters: - type: cross-account whitelist_from: expr: accounts.*.account url: https://redacted/path actions: # REDACTED # Each of these is a unique path to access an account (or organization or VPC or VPC-endpoints, etc.) There are a few common cases and a large number of unique, special cases. This, in turn, leads to a raft of special functions required to extract the information. - :py:func:`c7nlib.get_accounts` which depends on :py:meth:`CELFilter.get_accounts` - :py:func:`c7nlib.get_vpcs` which depends on :py:meth:`CELFilter.get_vpcs` - :py:func:`c7nlib.get_vpces` which depends on :py:meth:`CELFilter.get_vpces` - :py:func:`c7nlib.get_orgids` which depends on :py:meth:`CELFilter.get_orgids` - :py:func:`c7nlib.get_endpoints` which depends on :py:meth:`CELFilter.get_endpoints` - :py:func:`c7nlib.get_protocols` which depends on :py:meth:`CELFilter.get_protocols` - :py:func:`c7nlib.get_resource_policy` which depends on :py:meth:`CELFilter.get_protocols` - :py:func:`c7nlib.get_key_policy` which depends on :py:meth:`CELFilter.get_key_policy` - :py:func:`c7nlib.describe_subscription_filters` which depends on :py:attr:`CELFilter.manager` - :py:func:`c7nlib.describe_db_snapshot_attributes` which depends on :py:attr:`CELFilter.manager` - :py:func:`c7nlib.arn_split` Generally, these functions reach back into the :py:class:`CELFilter` instance for similarly-named methods that acquire the required data. Some of these seem to map directly to AWS boto3 functions. unused ------ See used_. Schema .. code:: yaml type: {'enum': ['unused']} value: {'type': 'boolean'} Used by aws.rds-subnet-group, aws.iam-profile, aws.iam-policy, aws.ami, aws.iam-role, aws.launch-config, aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 659 .. parsed-literal:: @SecurityGroup.filter_registry.register(unused) class UnusedSecurityGroup Filter to just vpc security groups that are not used. We scan all extant enis in the vpc to get a baseline set of groups in use. Then augment with those referenced by launch configs, and lambdas as they may not have extant resources in the vpc at a given moment. We also find any security group with references from other security group either within the vpc or across peered connections. Note this filter does not support classic security groups atm. :example: .. code-block:: yaml policies: - name: security-groups-unused resource: security-group filters: - unused - In :file:`c7n/resources/rds.py` 1474 .. parsed-literal:: @RDSSubnetGroup.filter_registry.register(unused) class UnusedRDSSubnetGroup Filters all launch rds subnet groups that are not in use but exist :example: .. code-block:: yaml policies: - name: rds-subnet-group-delete-unused resource: rds-subnet-group filters: - unused - In :file:`c7n/resources/iam.py` 373 .. parsed-literal:: @Role.filter_registry.register(unused) class UnusedIamRole Filter IAM roles that are either being used or not This filter has been deprecated. Please use the 'used' filter with the 'state' attribute to get unused iam roles Checks for usage on EC2, Lambda, ECS only :example: .. code-block:: yaml policies: - name: iam-roles-not-in-use resource: iam-role filters: - type: used state: false - In :file:`c7n/resources/iam.py` 597 .. parsed-literal:: @Policy.filter_registry.register(unused) class UnusedIamPolicies Filter IAM policies that are not being used :example: .. code-block:: yaml policies: - name: iam-policy-unused resource: iam-policy filters: - type: unused - In :file:`c7n/resources/iam.py` 758 .. parsed-literal:: @InstanceProfile.filter_registry.register(unused) class UnusedInstanceProfiles Filter IAM profiles that are not being used :example: .. code-block:: yaml policies: - name: iam-instance-profiles-not-in-use resource: iam-profile filters: - type: unused - In :file:`c7n/resources/ami.py` 212 .. parsed-literal:: @filters.register(unused) class ImageUnusedFilter Filters images based on usage true: image has no instances spawned from it false: image has instances spawned from it :example: .. code-block:: yaml policies: - name: ami-unused resource: ami filters: - type: unused value: true - In :file:`c7n/resources/asg.py` 1728 .. parsed-literal:: @LaunchConfig.filter_registry.register(unused) class UnusedLaunchConfig Filters all launch configurations that are not in use but exist :example: .. code-block:: yaml policies: - name: asg-unused-launch-config resource: launch-config filters: - unused Policies studied have 43 examples. .. code:: yaml name: parent-launch-config-unused-gt-60-days description: Delete unused launch configurations. resource: launch-config filters: - days: 60 op: gt type: age - unused actions: # REDACTED # .. code:: yaml name: parent-launch-config-unused-gt-90-days description: Check unused launch configurations, abandonded or unused resources needs clean up. resource: launch-config filters: - days: 90 op: gt type: age - unused actions: # REDACTED # .. code:: yaml name: launch-config-unused-gt-60-days description: Delete unused launch configurations. resource: launch-config filters: - days: 60 op: gt type: age - unused actions: # REDACTED # Each resource type is slightly different: - ami. See :py:class:`c7n.resources.ami.ImageUnusedFilter`. This looks at a union of all EC2 and ASG images. :: ! Resource["ImageId"] in ( set(C7N.filter._pull_ec2_images()) + set(C7N.filter._pull_asg_images()) ) - asg. See :py:class:`c7n.resources.asg.UnusedLaunchConfig`. :: ! Resource['LaunchConfigurationName'] in ( C7N.filter.manager.get_launch_configuration_names() ) - ebs. See :py:class:`c7n.resources.ebs.SnapshotUnusedFilter`. This looks at all AMI and ASG snapshots, as well as launch templates. :: ! Resource['SnapshotId'] in (set(C7N.filter._pull_asg_snapshots() + set(C7N.filter._pull_ami_snapshots())) - iam. - Role. See :py:class:`c7n.resources.iam.UnusedIamRole`. Gets ARN's using the role. :: ! Resource['Arn'] in C7N.filter.service_role_usage() && ! Resource['RoleName'] in C7N.filter.service_role_usage() - Policy. See :py:class:`c7n.resources.iam.UnusedIamPolicies`. :: ! (Resource['AttachmentCount'] > 0 || Resource.get('PermissionsBoundaryUsageCount', 0) > 0) - Instance. See :py:class:`c7n.resources.iam.UnusedInstanceProfiles`. :: ! Resource['Arn'] in C7N.filter.instance_profile_usage() && ! Resource['InstanceProfileName'] in C7N.filter.instance_profile_usage() - rds-subnet-group. See :py:class:`c7n.resources.rds.UnusedRDSSubnetGroup`. :: ! Resource['DBSubnetGroupName'] in C7N.filter.get_dbsubnet_group_used() - vpc. See :py:class:`c7n.resources.vpc.UnusedSecurityGroup`. :: ! Resource['GroupId'] in C7N.filter.scan_groups() and 'VpcId' in Resource This leads to a number of functions in the ``CELFilter`` class, depending on the resource type. - :py:func:`c7nlib.all_images` which depends on :py:meth:`CELFilter._pull_ec2_images` and :py:meth:`CELFilter._pull_asg_images`. - :py:func:`c7nlib.all_snapshots` which depends on :py:meth:`CELFilter._pull_asg_snapshots` and :py:meth:`CELFilter._pull_ami_snapshots` - :py:func:`c7nlib.all_launch_configuration_names` which depends on :py:meth:`CELFilter.manager.get_launch_configuration_names` - :py:func:`c7nlib.all_service_roles` which depends on :py:meth:`CELFilter.service_role_usage` - :py:func:`c7nlib.all_instance_profiles` which depends on :py:meth:`CELFilter.instance_profile_usage` - :py:func:`c7nlib.all_dbsubenet_groups` which depends on :py:meth:`CELFilter.get_dbsubnet_group_used` - :py:func:`c7nlib.all_scan_groups` which depends on :py:meth:`CELFilter.scan_groups` is-not-logging -------------- See `is-logging`_. Schema .. code:: yaml bucket: {'type': 'string'} prefix: {'type': 'string'} type: {'enum': ['is-not-logging']} Used by aws.app-elb, aws.elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 610 .. parsed-literal:: @filters.register(is-not-logging) class IsNotLoggingFilter Matches AppELBs that are NOT logging to S3. or do not match the optional bucket and/or prefix. :example: .. code-block:: yaml policies: - name: alb-is-not-logging-test resource: app-elb filters: - type: is-not-logging - name: alb-is-not-logging-bucket-and-prefix-test resource: app-elb filters: - type: is-not-logging bucket: prodlogs prefix: alblogs - In :file:`c7n/resources/elb.py` 829 .. parsed-literal:: @filters.register(is-not-logging) class IsNotLoggingFilter Matches ELBs that are NOT logging to S3. or do not match the optional bucket and/or prefix. :example: .. code-block:: yaml policies: - name: elb-is-not-logging-test resource: elb filters: - type: is-not-logging - name: is-not-logging-bucket-and-prefix-test resource: app-elb filters: - type: is-not-logging bucket: prodlogs prefix: alblogs Policies studied have 40 examples. .. code:: yaml name: classic-elb-require-logging-us-east-1 resource: elb filters: - bucket: redacted prefix: Logs type: is-not-logging actions: # REDACTED # .. code:: yaml name: classic-elb-require-logging-us-west-2 resource: elb filters: - bucket: redacted prefix: Logs type: is-not-logging actions: # REDACTED # .. code:: yaml name: application-elb-require-logging-us-east-1 resource: app-elb filters: - Type: application - bucket: redacted prefix: Logs type: is-not-logging actions: # REDACTED # This leads to a two functions in the ``CELFilter`` class, depending on the resource type. - :py:func:`c7nlib.get_access_log` is for `elb`, and depends on :py:class:`c7n.resources.elb.IsNotLoggingFilter` and :py:class:`c7n.resources.elb.IsLoggingFilter`. - :py:func:`c7nlib.get_load_balancer` is for `app-elb` and depends on :py:class:`c7n.resources.appelb.IsNotLoggingFilter` and :py:class:`c7n.resources.appelb.IsLoggingFilter`. health-event ------------ See `metrics`_. Schema .. code:: yaml statuses: {'type': 'array', 'items': {'type': 'string', 'enum': ['open', 'upcoming', 'closed']}} type: {'enum': ['health-event']} types: {'items': {'enum': ['AWS_EBS_DEGRADED_EBS_VOLUME_PERFORMANCE', 'AWS_EBS_VOLUME_LOST'], 'type': 'string'}, 'type': 'array'} Used by aws.ec2, aws.directconnect, aws.dynamodb-table, aws.cache-cluster, aws.acm-certificate, aws.emr, aws.app-elb, aws.elb, aws.ebs, aws.efs, aws.storage-gateway, aws.rds, aws.dms-instance, aws.directory Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ebs.py` 592 .. parsed-literal:: @filters.register(health-event) class HealthFilter Policies studied have 32 examples. .. code:: yaml name: ec2-health-event comment: Send daily EC2 PHD event notification to resource owners resource: ec2 filters: - statuses: - upcoming - open type: health-event - key: '"c7n:HealthEvent"[0].lastUpdatedTime' op: le type: value value: 1 value_type: age actions: # REDACTED # .. code:: yaml name: rds-health-event comment: Send daily RDS PHD event notification to resource owners resource: rds filters: - statuses: - upcoming - open type: health-event - key: '"c7n:HealthEvent"[0].lastUpdatedTime' op: le type: value value: 1 value_type: age actions: # REDACTED # .. code:: yaml name: ec2-health-event comment: Send daily EC2 PHD event notification to resource owners resource: ec2 filters: - statuses: - upcoming - open type: health-event - key: '"c7n:HealthEvent"[0].lastUpdatedTime' op: le type: value value: 1 value_type: age actions: # REDACTED # This may require some rework in the :py:class:`c7n.filters.health.HealthEventFilter` class. The class :py:meth:`c7n.filters.health.HealthEventFilter.process` method appears to provide all Health events for a given list of resources. It may be that a CEL ``Resource.get_health_events()`` should evaluate a ``C7N.health_events`` function that is a refactirubg of the ``process()`` method of the :py:class:`c7n.filters.health.HealthEventFilter` class. Because the filter features are mixins, they cannot reuse names like ``process``. There are two parts to this. 1. Getting raw health-events from the cloud provider. The :py:func:`celpy.c7nlib.get_raw_health_events` is refactored from the ``HealthEventFilter`` filter into :py:func:`celpy.c7nlib.get_raw_health_events` function. 2. Getting health events for a specific resource. The :py:func:`celpy.c7nlib.get_health_events` function builds a filter unique to the resource. This uses :py:func:`celpy.c7nlib.get_raw_health_events`. Generally, C7N requests in bunches of 10 per client connection. A worker pool processes the batches to keep from overwhelming AWS with health event requests. shield-enabled -------------- Schema .. code:: yaml state: {'type': 'boolean'} type: {'enum': ['shield-enabled']} Used by aws.hostedzone, aws.app-elb, aws.elb, aws.network-addr, aws.distribution, aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 934 .. parsed-literal:: @filters.register(shield-enabled) class ShieldEnabled Policies studied have 15 examples. .. code:: yaml name: enterprise-check-shield-advanced-enabled resource: account filters: - state: false type: shield-enabled actions: # REDACTED # .. code:: yaml name: enterprise-check-shield-advanced-enabled resource: account filters: - state: false type: shield-enabled actions: # REDACTED # .. code:: yaml name: enterprise-check-shield-advanced-enabled resource: account filters: - state: false type: shield-enabled actions: # REDACTED # This leads to two functions in the ``CELFilter`` class, depending on the resource type. - :py:func:`c7nlib.shield_protection` which depends on the :py:meth:`c7n.resources.shield.IsShieldProtected.process` method. This needs to be refactored and renamed to avoid collisions with other ``process()`` variants. Also depends on :py:meth:`c7n.resources.shield.IsShieldProtected.get_type_protections`, unmodified. - :py:func:`c7nlib.shield_subscription` which depends on :py:meth:`c7n.resources.account.ShieldEnabled.process` method. This needs to be refactored and renamed to avoid collisions with other ``process()`` variants. is-logging ---------- See `is-not-logging`_. Schema .. code:: yaml bucket: {'type': 'string'} prefix: {'type': 'string'} type: {'enum': ['is-logging']} Used by aws.app-elb, aws.elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 567 .. parsed-literal:: @filters.register(is-logging) class IsLoggingFilter Matches AppELBs that are logging to S3. bucket and prefix are optional :example: .. code-block:: yaml policies: - name: alb-is-logging-test resource: app-elb filters: - type: is-logging - name: alb-is-logging-bucket-and-prefix-test resource: app-elb filters: - type: is-logging bucket: prodlogs prefix: alblogs - In :file:`c7n/resources/elb.py` 786 .. parsed-literal:: @filters.register(is-logging) class IsLoggingFilter Matches ELBs that are logging to S3. bucket and prefix are optional :example: .. code-block:: yaml policies: - name: elb-is-logging-test resource: elb filters: - type: is-logging - name: elb-is-logging-bucket-and-prefix-test resource: elb filters: - type: is-logging bucket: prodlogs prefix: elblogs Policies studied have 8 examples. .. code:: yaml name: correct-elb-logging-region-1 resource: elb filters: - type: is-logging - key: DNSName op: regex type: value value: (?!.*eu-west-2.*) - key: Attributes.AccessLog.S3BucketName op: ne type: value value: capone-redacted actions: # REDACTED # .. code:: yaml name: correct-elb-logging-region-2 resource: elb filters: - type: is-logging - key: DNSName op: regex type: value value: (?!.*eu-west-1.*) - key: Attributes.AccessLog.S3BucketName op: ne type: value value: capone-redacted actions: # REDACTED # .. code:: yaml name: correct-elb-logging-region-1 resource: elb filters: - type: is-logging - key: DNSName op: regex type: value value: (?!.*eu-west-2.*) - key: Attributes.AccessLog.S3BucketName op: ne type: value value: capone-redacted actions: # REDACTED # This is based on `is-not-logging`_. used ---- See unused_. Schema .. code:: yaml state: {'type': 'boolean'} type: {'enum': ['used']} Used by aws.iam-profile, aws.iam-role, aws.iam-policy, aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 692 .. parsed-literal:: @SecurityGroup.filter_registry.register(used) class UsedSecurityGroup Filter to security groups that are used. This operates as a complement to the unused filter for multi-step workflows. :example: .. code-block:: yaml policies: - name: security-groups-in-use resource: security-group filters: - used - In :file:`c7n/resources/iam.py` 341 .. parsed-literal:: @Role.filter_registry.register(used) class UsedIamRole Filter IAM roles that are either being used or not Checks for usage on EC2, Lambda, ECS only :example: .. code-block:: yaml policies: - name: iam-role-in-use resource: iam-role filters: - type: used state: true - In :file:`c7n/resources/iam.py` 575 .. parsed-literal:: @Policy.filter_registry.register(used) class UsedIamPolicies Filter IAM policies that are being used :example: .. code-block:: yaml policies: - name: iam-policy-used resource: iam-policy filters: - type: used - In :file:`c7n/resources/iam.py` 729 .. parsed-literal:: @InstanceProfile.filter_registry.register(used) class UsedInstanceProfiles Filter IAM profiles that are being used :example: .. code-block:: yaml policies: - name: iam-instance-profiles-in-use resource: iam-profile filters: - type: used Policies studied have 5 examples. .. code:: yaml name: security-group-unused-unmark comment: For SG's in use, marked as unused - unmark them resource: security-group filters: - tag:maid_status: not-null - used actions: # REDACTED # .. code:: yaml name: security-group-unused-unmark comment: For SG's in use, marked as unused - unmark them resource: security-group filters: - tag:sg_unused: not-null - used actions: # REDACTED # .. code:: yaml name: tidyup-security-group-unused-unmark comment: For SG's in use marked as unused - unmark them resource: security-group filters: - tag:housekeep_unused_sg: not-null - used actions: # REDACTED # waf-enabled ----------- Schema .. code:: yaml state: {'type': 'boolean'} type: {'enum': ['waf-enabled']} web-acl: {'type': 'string'} Used by aws.app-elb, aws.distribution Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 205 .. parsed-literal:: @AppELB.filter_registry.register(waf-enabled) class WafEnabled - In :file:`c7n/resources/cloudfront.py` 147 .. parsed-literal:: @Distribution.filter_registry.register(waf-enabled) class IsWafEnabled Policies studied have 3 examples. .. code:: yaml name: uk-compliance-cloudfront-create-web-acl resource: distribution filters: - state: false type: waf-enabled web-acl: WebACL to allow or restrict by IP actions: # REDACTED # .. code:: yaml name: uk-compliance-cloudfront-hourly-web-acl resource: distribution filters: - state: false type: waf-enabled web-acl: WebACL to allow or restrict by IP actions: # REDACTED # .. code:: yaml name: uk-compliance-cloudfront-update-web-acl resource: distribution filters: - state: false type: waf-enabled web-acl: WebACL to allow or restrict by IP actions: # REDACTED # There appear to be two parts to this: (1) getting ACL-ids, and then (2) checking to see if the filter's web-acl value is in the list of ACL-ids for this resource. This leads to a a function in the ``CELFilter`` class: - :py:func:`c7nlib.web_acls` depends on :py:meth:`c7n.resources.cloudfront.IsWafEnabled.process` to get the ACL-ids. The rest of the prcessing can be exposed in CEL. network-location ---------------- Schema .. code:: yaml compare: {'type': 'array', 'description': 'Which elements of network location should be considered when matching.', 'default': ['resource', 'subnet', 'security-group'], 'items': {'enum': ['resource', 'subnet', 'security-group']}} ignore: {'type': 'array', 'items': {'type': 'object'}} key: {'type': 'string', 'description': 'The attribute expression that should be matched on'} match: {'type': 'string', 'enum': ['equal', 'not-equal'], 'default': 'non-equal'} max-cardinality: {'type': 'integer', 'default': 1, 'title': ''} missing-ok: {'type': 'boolean', 'default': False, 'description': 'How to handle missing keys on elements, by default this causesresources to be considered not-equal'} type: {'enum': ['network-location']} Used by aws.ec2, aws.cache-cluster, aws.app-elb, aws.lambda, aws.elb, aws.rds, aws.rds-cluster, aws.redshift, aws.asg, aws.eni No implementation for network-location. Policies studied have 2 examples. .. code:: yaml name: ec2-sg-shopping description: Find all ec2 instances that are using another ASVs security groups. resource: ec2 filters: - compare: - resource - security-group ignore: - tag:ASV: ASVredacted - tag:ASV: ASVredacted - tag:ASV: ASVredacted key: tag:ASV type: network-location - key: VpcId op: in type: value value: - vpc-redacted - vpc-redacted - vpc-redacted - vpc-redacted - vpc-redacted - vpc-redacted actions: # REDACTED # .. code:: yaml name: rds-sg-shopping description: Find all rds instances that are using another ASVs security groups. resource: rds filters: - key: DBSubnetGroup.VpcId op: in type: value value: - vpc-redacted - vpc-redacted - vpc-redacted - vpc-redacted - vpc-redacted - vpc-redacted - compare: - resource - security-group ignore: - tag:ASV: ASVredacted - tag:ASV: ASVredacted - tag:ASV: ASVredacted key: tag:ASV type: network-location actions: # REDACTED # A number of resources depend on :py:class:`c7n.filters.vpc.NetworkLocation` for the core implementation. The "ec2" implementation diverges slightly from the superclass. From the documentation. On a network attached resource, determine intersection of security-group attributes, subnet attributes, and resource attributes. The use case is a bit specialized, for most use cases using `subnet` and `security-group` filters suffice. but say for example you wanted to verify that an ec2 instance was only using subnets and security groups with a given tag value, and that tag was not present on the resource. It appears that the "compare-ignore" rules can be optimized into an explicit CEL expression to describe the related items and their relationshiup. This legacy filter :: resource: ec2 filters: - type: network-location compare: ["resource","security-group"] key: "tag:TEAM_NAME" ignore: - "tag:TEAM_NAME": Enterprise May be this :: Resource.SubnetId.subnet()["Tags"]["TEAM_NAME"] == Resource["Tags"]["TEAM_NAME"] && Resource["Tags"]["TEAM_NAME"] != "Enterprise" This doesn't seem to require an additional c7nlib function. The features appear to be available in other functions to fetch the related subnet and security group for a resource. finding (no examples) --------------------- Schema .. code:: yaml query: {'type': 'object'} region: {'type': 'string'} type: {'enum': ['finding']} Used by aws.ssm-managed-instance, aws.iam-policy, aws.batch-definition, aws.iam-group, aws.shield-protection, aws.ecs, aws.fsx-backup, aws.ecs-container-instance, aws.eks, aws.support-case, aws.vpc, aws.rds-subscription, aws.network-addr, aws.message-broker, aws.redshift, aws.sagemaker-notebook, aws.glue-connection, aws.directory, aws.ebs-snapshot, aws.rds-cluster-param-group, aws.customer-gateway, aws.lambda-layer, aws.ecs-task, aws.subnet, aws.ec2, aws.cfn, aws.cloud-directory, aws.r53domain, aws.transit-gateway, aws.sns, aws.iam-role, aws.kinesis-analytics, aws.rds-param-group, aws.snowball-cluster, aws.codebuild, aws.efs, aws.elasticbeanstalk, aws.cache-snapshot, aws.security-group, aws.waf-regional, aws.dynamodb-table, aws.kms-key, aws.step-machine, aws.s3, aws.eni, aws.snowball, aws.elasticbeanstalk-environment, aws.lambda, aws.alarm, aws.ami, aws.sagemaker-endpoint-config, aws.app-elb-target-group, aws.simpledb, aws.hsm-client, aws.directconnect, aws.nat-gateway, aws.sagemaker-job, aws.emr, aws.glue-dev-endpoint, aws.rest-account, aws.fsx, aws.rest-resource, aws.codepipeline, aws.dlm-policy, aws.rds-cluster-snapshot, aws.hsm-hapg, aws.ecs-task-definition, aws.firehose, aws.secrets-manager, aws.asg, aws.rest-vpclink, aws.vpc-endpoint, aws.redshift-subnet-group, aws.iam-profile, aws.transit-attachment, aws.rest-stage, aws.rest-api, aws.distribution, aws.cache-subnet-group, aws.ecs-service, aws.event-rule-target, aws.identity-pool, aws.ssm-activation, aws.rds-snapshot, aws.app-elb, aws.ecr, aws.peering-connection, aws.ebs, aws.config-rule, aws.dax, aws.kinesis, aws.rrset, aws.batch-compute, aws.kms, aws.cloudtrail, aws.dynamodb-backup, aws.dms-endpoint, aws.sqs, aws.sagemaker-endpoint, aws.gamelift-build, aws.shield-attack, aws.dms-instance, aws.backup-plan, aws.key-pair, aws.iot, aws.hostedzone, aws.log-group, aws.rds-subnet-group, aws.cache-cluster, aws.hsm, aws.vpn-gateway, aws.sagemaker-transform-job, aws.route-table, aws.dynamodb-stream, aws.redshift-snapshot, aws.efs-mount-target, aws.codecommit, aws.glacier, aws.elasticsearch, aws.event-rule, aws.ssm-parameter, aws.rds, aws.sagemaker-model, aws.account, aws.cloudhsm-cluster, aws.waf, aws.vpn-connection, aws.iam-certificate, aws.iam-user, aws.streaming-distribution, aws.ml-model, aws.network-acl, aws.health-event, aws.launch-config, aws.rds-cluster, aws.storage-gateway, aws.healthcheck, aws.opswork-cm, aws.opswork-stack, aws.user-pool, aws.acm-certificate, aws.datapipeline, aws.elb, aws.gamelift-fleet, aws.cloudsearch, aws.internet-gateway No implementation for finding. Policies studied have 0 examples. has-inline-policy (no examples) ------------------------------- Schema .. code:: yaml type: {'enum': ['has-inline-policy']} value: {'type': 'boolean'} Used by aws.iam-user, aws.iam-role, aws.iam-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 413 .. parsed-literal:: @Role.filter_registry.register(has-inline-policy) class IamRoleInlinePolicy Filter IAM roles that have an inline-policy attached True: Filter roles that have an inline-policy False: Filter roles that do not have an inline-policy :example: .. code-block:: yaml policies: - name: iam-roles-with-inline-policies resource: iam-role filters: - type: has-inline-policy value: True - In :file:`c7n/resources/iam.py` 1004 .. parsed-literal:: @User.filter_registry.register(has-inline-policy) class IamUserInlinePolicy Filter IAM users that have an inline-policy attached True: Filter users that have an inline-policy False: Filter users that do not have an inline-policy - In :file:`c7n/resources/iam.py` 1613 .. parsed-literal:: @Group.filter_registry.register(has-inline-policy) class IamGroupInlinePolicy Filter IAM groups that have an inline-policy based on boolean value: True: Filter all groups that have an inline-policy attached False: Filter all groups that do not have an inline-policy attached :example: .. code-block:: yaml - name: iam-groups-with-inline-policy resource: iam-group filters: - type: has-inline-policy value: True Policies studied have 0 examples. default-vpc (no examples) ------------------------- Schema .. code:: yaml type: {'enum': ['default-vpc']} Used by aws.ec2, aws.app-elb, aws.elb, aws.app-elb-target-group, aws.redshift, aws.rds, aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/redshift.py` 78 .. parsed-literal:: @filters.register(default-vpc) class DefaultVpc Matches if an redshift database is in the default vpc :example: .. code-block:: yaml policies: - name: redshift-default-vpc resource: redshift filters: - default-vpc - In :file:`c7n/resources/appelb.py` 842 .. parsed-literal:: @filters.register(default-vpc) class AppELBDefaultVpcFilter Filter all ELB that exist within the default vpc :example: .. code-block:: yaml policies: - name: appelb-in-default-vpc resource: app-elb filters: - default-vpc - In :file:`c7n/resources/appelb.py` 1023 .. parsed-literal:: @AppELBTargetGroup.filter_registry.register(default-vpc) class AppELBTargetGroupDefaultVpcFilter Filter all application elb target groups within the default vpc :example: .. code-block:: yaml policies: - name: appelb-targetgroups-default-vpc resource: app-elb-target-group filters: - default-vpc - In :file:`c7n/resources/vpc.py` 767 .. parsed-literal:: @SecurityGroup.filter_registry.register(default-vpc) class SGDefaultVpc Filter that returns any security group that exists within the default vpc :example: .. code-block:: yaml policies: - name: security-group-default-vpc resource: security-group filters: - default-vpc - In :file:`c7n/resources/rds.py` 273 .. parsed-literal:: @filters.register(default-vpc) class DefaultVpc Matches if an rds database is in the default vpc :example: .. code-block:: yaml policies: - name: default-vpc-rds resource: rds filters: - default-vpc - In :file:`c7n/resources/ec2.py` 656 .. parsed-literal:: @filters.register(default-vpc) class DefaultVpc Matches if an ec2 database is in the default vpc - In :file:`c7n/resources/elb.py` 748 .. parsed-literal:: @filters.register(default-vpc) class DefaultVpc Matches if an elb database is in the default vpc :example: .. code-block:: yaml policies: - name: elb-default-vpc resource: elb filters: - type: default-vpc Policies studied have 0 examples. healthcheck-protocol-mismatch (no examples) ------------------------------------------- Schema .. code:: yaml type: {'enum': ['healthcheck-protocol-mismatch']} Used by aws.app-elb, aws.elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 791 .. parsed-literal:: @filters.register(healthcheck-protocol-mismatch) class AppELBHealthCheckProtocolMismatchFilter Filter AppELBs with mismatched health check protocols A mismatched health check protocol is where the protocol on the target group does not match the load balancer health check protocol :example: .. code-block:: yaml policies: - name: appelb-healthcheck-mismatch resource: app-elb filters: - healthcheck-protocol-mismatch - In :file:`c7n/resources/elb.py` 711 .. parsed-literal:: @filters.register(healthcheck-protocol-mismatch) class HealthCheckProtocolMismatch Filters ELB that have a healtch check protocol mismatch The mismatch occurs if the ELB has a different protocol to check than the associated instances allow to determine health status. :example: .. code-block:: yaml policies: - name: elb-healthcheck-mismatch resource: elb filters: - type: healthcheck-protocol-mismatch Policies studied have 0 examples. Singleton/Non-Bool Filters ========================== launch-config ------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['launch-config']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/asg.py` 161 .. parsed-literal:: @filters.register(launch-config) class LaunchConfigFilter Filter asg by launch config attributes. :example: .. code-block:: yaml policies: - name: launch-configs-with-public-address resource: asg filters: - type: launch-config key: AssociatePublicIpAddress value: true Policies studied have 103 examples. .. code:: yaml name: asg-using-key-pair-notify-new comment: Any ASG that creates EC2 instances that use a KeyName (key pair) will generate a notification resource: asg filters: - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - key: KeyName type: launch-config value: not-null actions: # REDACTED # .. code:: yaml name: asg-large-instance-notify comment: Notify any user who creates an ASG that will launch instances that use an instance type that is considered "large" (generally > $1/hour) resource: asg filters: - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - key: InstanceType op: in type: launch-config value_from: expr: all.large_instance_types.* format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: asg-using-key-pair-notify-new comment: Any ASG that creates EC2 instances that use a KeyName (key pair) will generate a notification resource: asg filters: - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - key: KeyName type: launch-config value: not-null actions: # REDACTED # instance-age ------------ Schema .. code:: yaml days: {'type': 'number'} hours: {'type': 'number'} minutes: {'type': 'number'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['instance-age']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 615 .. parsed-literal:: @filters.register(instance-age) class InstanceAgeFilter Filters instances based on their age (in days) :Example: .. code-block:: yaml policies: - name: ec2-30-days-plus resource: ec2 filters: - type: instance-age op: ge days: 30 Policies studied have 94 examples. .. code:: yaml name: ec2-invalid-asv-value-tag comment: Tag any instances that use an ASV that isn't valid. Owner will be notified in a later policy. resource: ec2 filters: - days: 0.084 op: gte type: instance-age - tag:aws:autoscaling:groupName: absent - tag:custodian_asv: absent - key: tag:ASV op: not-in type: value value_from: expr: all_values.* format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: parent-ec2-ancient-image-new comment: Terminate any new instance whose AMI is over 60 days old. resource: ec2 filters: - tag:aws:autoscaling:groupName: absent - key: State.Name op: ne type: value value: terminated - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - days: 60 op: ge type: image-age - days: 0.011 type: instance-uptime - days: 0.084 op: less-than type: instance-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - key: tag:ASV op: not-in type: value value: - ASVredacted actions: # REDACTED # .. code:: yaml name: parent-ec2-untagged-mark comment: Require proper tagging for all EC2 instances that have been up at least 15 minutes. resource: ec2 filters: - days: 0.011 type: instance-age - tag:aws:autoscaling:groupName: absent - tag:fs_custodian_tagging: absent - key: State.Name op: ne type: value value: terminated - or: - or: - not: - and: - or: - and: - tag:ASV: not-null - key: tag:ASV op: not-equal type: value value: '' value_type: normalize - and: - tag:BA: not-null - key: tag:BA op: not-equal type: value value: '' value_type: normalize - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - key: tag:GroupName op: not-in type: value value: - EMMO - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - or: - tag:ApplicationName: absent - tag:Environment: absent - tag:Uptime: absent - key: tag:ApplicationName op: eq type: value value: '' value_type: normalize - key: tag:Environment op: eq type: value value: '' value_type: normalize - key: tag:Uptime op: eq type: value value: '' value_type: normalize actions: # REDACTED # listener -------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} matched: {'type': 'boolean'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['listener']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.app-elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 666 .. parsed-literal:: @filters.register(listener) class AppELBListenerFilter Filter ALB based on matching listener attributes Adding the `matched` flag will filter on previously matched listeners :example: .. code-block:: yaml policies: - name: app-elb-invalid-ciphers resource: app-elb filters: - type: listener key: Protocol value: HTTPS - type: listener key: SslPolicy value: ['ELBSecurityPolicy-TLS-1-1-2017-01','ELBSecurityPolicy-TLS-1-2-2017-01'] op: ni matched: true actions: - type: modify-listener sslpolicy: "ELBSecurityPolicy-TLS-1-2-2017-01" Policies studied have 32 examples. .. code:: yaml name: parent-app-elb-ssl-require-tls12 resource: app-elb filters: - key: Protocol type: listener value: HTTPS - key: SslPolicy matched: true op: ni type: listener value: - ELBSecurityPolicy-TLS-1-2-2017-01 actions: # REDACTED # .. code:: yaml name: parent-app-elb-ssl-require-tls12 resource: app-elb filters: - key: Protocol type: listener value: HTTPS - key: SslPolicy matched: true op: ni type: listener value: - ELBSecurityPolicy-TLS-1-2-2017-01 actions: # REDACTED # .. code:: yaml name: app-elb-invalid-ciphers-report comment: Report on any ALB that uses an invalid SSL policy. resource: app-elb filters: - or: - and: - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - tag:OwnerEID: not-null - key: tag:OwnerEID op: not-equal type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (^[A-Za-z]{3}[0-9]{3}$) - key: Protocol type: listener value: HTTPS - key: SslPolicy matched: true op: ni type: listener value: - ELBSecurityPolicy-TLS-1-1-2017-01 - ELBSecurityPolicy-TLS-1-2-2017-01 - key: tag:ASV op: not-in type: value value_from: expr: all.exceptions.alb.security.["tag:ASV"][].*[] format: json url: s3://redacted/bucket - key: tag:CMDBEnvironment op: not-in type: value value_from: expr: all.exceptions.alb.security.["tag:CMDBEnvironment"][].*[] format: json url: s3://redacted/bucket actions: # REDACTED # vpc-id ------ Schema .. code:: yaml default: {'type': 'object'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['vpc-id']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/asg.py` 662 .. parsed-literal:: @filters.register(vpc-id) class VpcIdFilter Filters ASG based on the VpcId This filter is available as a ValueFilter as the vpc-id is not natively associated to the results from describing the autoscaling groups. :example: .. code-block:: yaml policies: - name: asg-vpc-xyz resource: asg filters: - type: vpc-id value: vpc-12ab34cd Policies studied have 30 examples. .. code:: yaml name: asg-default-vpc-delete-new comment: Any ASG created in any default VPC will be immediately deleted. resource: asg filters: - op: in type: vpc-redacted value_from: expr: fs_analytical_dev.default_vpcs.* format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: asg-default-vpc-delete-new comment: Any ASG created in any default VPC will be immediately deleted. resource: asg filters: - op: in type: vpc-redacted value_from: expr: fs_analytical_qa.default_vpcs.* format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: asg-default-vpc-delete-new comment: Any ASG created in any default VPC will be immediately deleted. resource: asg filters: - op: in type: vpc-redacted value_from: expr: fs_core_cas_qa.default_vpcs.* format: json url: s3://redacted/bucket actions: # REDACTED # ebs --- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} operator: {'enum': ['and', 'or']} skip-devices: {'type': 'array', 'items': {'type': 'string'}} type: {'enum': ['ebs']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 250 .. parsed-literal:: @filters.register(ebs) class AttachedVolume EC2 instances with EBS backed volume Filters EC2 instances with EBS backed storage devices (non ephemeral) :Example: .. code-block:: yaml policies: - name: ec2-encrypted-ebs-volumes resource: ec2 filters: - type: ebs key: Encrypted value: true Policies studied have 27 examples. .. code:: yaml name: enterprise-ec2-create-snapshot comment: Creates nightly backups of EC2 instances resource: ec2 filters: - key: Encrypted type: ebs value: true - or: - tag:aws:elasticmapreduce:instance-group-role: absent - tag:aws:elasticmapreduce:job-flow-id: absent - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.ec2.["snapshot"][].["tag:CMDBEnvironment"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.*[].ebs."OPS-11".["tag:CMDBEnvironment"][][] format: json url: s3://redacted/bucket - key: tag:ASV op: ne type: value value: ASVredacted actions: # REDACTED # .. code:: yaml name: ec2-create-snapshot comment: Creates nightly backups of EC2 instances resource: ec2 filters: - key: Encrypted type: ebs value: true - or: - tag:aws:elasticmapreduce:instance-group-role: absent - tag:aws:elasticmapreduce:job-flow-id: absent actions: # REDACTED # .. code:: yaml name: ec2-require-encrypted-volumes description: ISRM 10 - All EC2 instances will be launched with encrypted EBS volumes. resource: ec2 filters: - key: detail.userAgent op: not-equal type: event value: autoscaling.amazonaws.com - key: Encrypted type: ebs value: false - key: detail.userIdentity.sessionContext.sessionIssuer.userName op: ne type: event value: capone-redacted actions: # REDACTED # instance-uptime --------------- Schema .. code:: yaml days: {'type': 'number'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['instance-uptime']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 604 .. parsed-literal:: @filters.register(instance-uptime) class UpTimeFilter Policies studied have 12 examples. .. code:: yaml name: parent-ec2-ancient-image-new comment: Terminate any new instance whose AMI is over 60 days old. resource: ec2 filters: - tag:aws:autoscaling:groupName: absent - key: State.Name op: ne type: value value: terminated - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - days: 60 op: ge type: image-age - days: 0.011 type: instance-uptime - days: 0.084 op: less-than type: instance-age - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - key: tag:ASV op: not-in type: value value: - ASVredacted actions: # REDACTED # .. code:: yaml name: ec2-invalid-asv-value-mark comment: Report on any instances that use an ASV that isn't valid. resource: ec2 filters: - days: 0.011 type: instance-uptime - tag:aws:autoscaling:groupName: absent - tag:custodian_asv: absent - key: tag:ASV op: not-in type: value value_from: expr: all_values.* format: json url: s3://redacted/bucket actions: # REDACTED # .. code:: yaml name: ec2-invalid-asv-value-mark comment: Report on any instances that use an ASV that isn't valid. resource: ec2 filters: - days: 0.011 type: instance-uptime - tag:aws:autoscaling:groupName: absent - tag:custodian_asv: absent - key: tag:ASV op: not-in type: value value_from: expr: all_values.* format: json url: s3://redacted/bucket actions: # REDACTED # state-age --------- Schema .. code:: yaml days: {'type': 'number'} op: {'type': 'string', 'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['state-age']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 194 .. parsed-literal:: @filters.register(state-age) class StateTransitionAge Age an instance has been in the given state. .. code-block:: yaml policies: - name: ec2-state-running-7-days resource: ec2 filters: - type: state-age op: ge days: 7 Policies studied have 7 examples. .. code:: yaml name: enterprise-unused-stopped-ec2-with-ancient-images resource: ec2 filters: - tag:proxy: absent - days: 60 op: gte type: image-age - State.Name: stopped - days: 14 op: gte type: state-age - key: IamInstanceProfile.Arn op: ni type: value value_from: expr: exemptions.ec2.rehydration.["IamInstanceProfile.Arn"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.ec2.rehydration.["tag:CMDBEnvironment"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:ASV op: ni type: value value_from: expr: exemptions.ec2.rehydration.["tag:ASV"][].*[].*[] format: json url: s3://redacted/bucket - key: ImageId op: ni type: value value_from: expr: exemptions.ec2.rehydration.["ImageId"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.*[].ami."ISRM-1".["tag:CMDBEnvironment"][][] format: json url: s3://redacted/bucket - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - tag:c7n-ancient-image: absent actions: # REDACTED # .. code:: yaml name: enterprise-unused-stopped-ec2-with-ancient-image-delete resource: ec2 filters: - tag:proxy: absent - days: 60 op: gte type: image-age - State.Name: stopped - days: 14 op: gte type: state-age - key: IamInstanceProfile.Arn op: ni type: value value_from: expr: exemptions.ec2.rehydration.["IamInstanceProfile.Arn"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.ec2.rehydration.["tag:CMDBEnvironment"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:ASV op: ni type: value value_from: expr: exemptions.ec2.rehydration.["tag:ASV"][].*[].*[] format: json url: s3://redacted/bucket - key: ImageId op: ni type: value value_from: expr: exemptions.ec2.rehydration.["ImageId"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.*[].ami."ISRM-1".["tag:CMDBEnvironment"][][] format: json url: s3://redacted/bucket - key: tag:ASV op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:ASV", `[]`) format: json url: s3://redacted/bucket - key: tag:BA op: ni type: value value_from: expr: not_null(exceptions."{account_id}"."ec2/ami rehydration(si-2.aws.01)"."tag:BA", `[]`) format: json url: s3://redacted/bucket - op: terminate tag: c7n-ancient-image type: marked-for-op actions: # REDACTED # .. code:: yaml name: ec2-stopped-extended-period-terminate-skiers comment: Terminate instances which are stopped for more than 7 days. resource: ec2 filters: - days: 7 op: gt type: state-age actions: # REDACTED # password-policy --------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['password-policy']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 301 .. parsed-literal:: @filters.register(password-policy) class AccountPasswordPolicy Check an account's password policy. Note that on top of the default password policy fields, we also add an extra key, PasswordPolicyConfigured which will be set to true or false to signify if the given account has attempted to set a policy at all. :example: .. code-block:: yaml policies: - name: password-policy-check resource: account region: us-east-1 filters: - type: password-policy key: MinimumPasswordLength value: 10 op: ge - type: password-policy key: RequireSymbols value: true Policies studied have 5 examples. .. code:: yaml name: aws-strong-password comment: Policy scans to make sure accounts have a strong accounts policy resource: account filters: - key: MinimumPasswordLength op: greater-than type: password-policy value: 12 - key: RequireSymbols type: password-policy value: true - key: RequireNumbers type: password-policy value: true - key: RequireUppercaseCharacters type: password-policy value: true - key: RequireLowercaseCharacters type: password-policy value: true actions: # REDACTED # .. code:: yaml name: aws-strong-password comment: Policy scans to make sure accounts have a strong accounts policy resource: account filters: - key: MinimumPasswordLength op: greater-than type: password-policy value: 12 - key: RequireSymbols type: password-policy value: true - key: RequireNumbers type: password-policy value: true - key: RequireUppercaseCharacters type: password-policy value: true - key: RequireLowercaseCharacters type: password-policy value: true actions: # REDACTED # .. code:: yaml name: aws-strong-password comment: Policy scans to make sure accounts have a strong accounts policy resource: account filters: - key: MinimumPasswordLength op: greater-than type: password-policy value: 12 - key: RequireSymbols type: password-policy value: true - key: RequireNumbers type: password-policy value: true - key: RequireUppercaseCharacters type: password-policy value: true - key: RequireLowercaseCharacters type: password-policy value: true actions: # REDACTED # reserved-concurrency -------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['reserved-concurrency']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.lambda Resource Type Implementations for {function.name}: - In :file:`c7n/resources/awslambda.py` 136 .. parsed-literal:: @filters.register(reserved-concurrency) class ReservedConcurrency Policies studied have 4 examples. .. code:: yaml name: lambda-reserve-concurrency-absent-daily description: Email notification to setup lambda reserve concurrency resource: lambda filters: - type: reserved-concurrency value: absent - key: VpcConfig.VpcId op: regex type: value value: vpc-redacted actions: # REDACTED # .. code:: yaml name: lambda-reserve-concurrency-above-10-daily description: Setup lambda reserve concurrency to 10 for any function that have above 10 resource: lambda filters: - op: greater-than type: reserved-concurrency value: 10 - key: VpcConfig.VpcId op: regex type: value value: vpc-redacted - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted actions: # REDACTED # .. code:: yaml name: lambda-reserve-concurrency-absent-weekly description: Email notification to setup lambda reserve concurrency resource: lambda filters: - type: reserved-concurrency value: absent - key: VpcConfig.VpcId op: regex type: value value: vpc-redacted actions: # REDACTED # access-key ---------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['access-key']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.iam-user Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 1124 .. parsed-literal:: @User.filter_registry.register(access-key) class UserAccessKey Filter IAM users based on access-key values :example: .. code-block:: yaml policies: - name: iam-users-with-active-keys resource: iam-user filters: - type: access-key key: Status value: Active Policies studied have 2 examples. .. code:: yaml name: iam-credentials-old comment: Detect all IAM credentials older than 60 days resource: iam-user filters: - key: PolicyName type: policy value: AdministratorAccess - key: Status type: access-key value: Active - key: CreateDate op: greater-than type: access-key value: 60 value_type: age actions: # REDACTED # .. code:: yaml name: iam-credentials-old comment: Detect all IAM credentials older than 60 days resource: iam-user filters: - key: PolicyName type: policy value: AdministratorAccess - key: Status type: access-key value: Active - key: CreateDate op: greater-than type: access-key value: 60 value_type: age actions: # REDACTED # mfa-device ---------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['mfa-device']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.iam-user Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 1178 .. parsed-literal:: @User.filter_registry.register(mfa-device) class UserMfaDevice Filter iam-users based on mfa-device status :example: .. code-block:: yaml policies: - name: mfa-enabled-users resource: iam-user filters: - type: mfa-device key: UserName value: not-null Policies studied have 1 examples. .. code:: yaml name: iam-user-no-mfa comment: Detect all IAM users not using MFAs resource: iam-user filters: - key: MFADevices type: mfa-device value: [] actions: # REDACTED # policy ------ Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['policy']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.iam-user Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 1034 .. parsed-literal:: @User.filter_registry.register(policy) class UserPolicy Filter IAM users based on attached policy values :example: .. code-block:: yaml policies: - name: iam-users-with-admin-access resource: iam-user filters: - type: policy key: PolicyName value: AdministratorAccess Policies studied have 1 examples. .. code:: yaml name: iam-credentials-old comment: Detect all IAM credentials older than 60 days resource: iam-user filters: - key: PolicyName type: policy value: AdministratorAccess - key: Status type: access-key value: Active - key: CreateDate op: greater-than type: access-key value: 60 value_type: age actions: # REDACTED # key-rotation-status ------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['key-rotation-status']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.kms-key Resource Type Implementations for {function.name}: - In :file:`c7n/resources/kms.py` 80 .. parsed-literal:: @Key.filter_registry.register(key-rotation-status) class KeyRotationStatus Filters KMS keys by the rotation status :example: .. code-block:: yaml policies: - name: kms-key-disabled-rotation resource: kms-key filters: - type: key-rotation-status key: KeyRotationEnabled value: false Policies studied have 1 examples. .. code:: yaml name: kms-key-no-rotation comment: Detect all keys that have key rotation disabled resource: kms-key filters: - key: KeyRotationEnabled type: key-rotation-status value: false actions: # REDACTED # group (no examples) ------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['group']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.iam-user Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 1080 .. parsed-literal:: @User.filter_registry.register(group) class GroupMembership Filter IAM users based on attached group values :example: .. code-block:: yaml policies: - name: iam-users-in-admin-group resource: iam-user filters: - type: group key: GroupName value: Admins Policies studied have 0 examples. iam-summary (no examples) ------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['iam-summary']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 228 .. parsed-literal:: @filters.register(iam-summary) class IAMSummary Return annotated account resource if iam summary filter matches. Some use cases include, detecting root api keys or mfa usage. Example iam summary wrt to matchable fields:: { "AccessKeysPerUserQuota": 2, "AccountAccessKeysPresent": 0, "AccountMFAEnabled": 1, "AccountSigningCertificatesPresent": 0, "AssumeRolePolicySizeQuota": 2048, "AttachedPoliciesPerGroupQuota": 10, "AttachedPoliciesPerRoleQuota": 10, "AttachedPoliciesPerUserQuota": 10, "GroupPolicySizeQuota": 5120, "Groups": 1, "GroupsPerUserQuota": 10, "GroupsQuota": 100, "InstanceProfiles": 0, "InstanceProfilesQuota": 100, "MFADevices": 3, "MFADevicesInUse": 2, "Policies": 3, "PoliciesQuota": 1000, "PolicySizeQuota": 5120, "PolicyVersionsInUse": 5, "PolicyVersionsInUseQuota": 10000, "Providers": 0, "RolePolicySizeQuota": 10240, "Roles": 4, "RolesQuota": 250, "ServerCertificates": 0, "ServerCertificatesQuota": 20, "SigningCertificatesPerUserQuota": 2, "UserPolicySizeQuota": 2048, "Users": 5, "UsersQuota": 5000, "VersionsPerPolicyQuota": 5, } For example to determine if an account has either not been enabled with root mfa or has root api keys. .. code-block:: yaml policies: - name: root-keys-or-no-mfa resource: account filters: - type: iam-summary key: AccountMFAEnabled value: true op: eq value_type: swap Policies studied have 0 examples. s3-public-block (no examples) ----------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['s3-public-block']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 1066 .. parsed-literal:: @filters.register(s3-public-block) class S3PublicBlock Check for s3 public blocks on an account. https://docs.aws.amazon.com/AmazonS3/latest/dev/access-control-block-public-access.html Policies studied have 0 examples. rest-integration (no examples) ------------------------------ Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} method: {'type': 'string', 'enum': ['all', 'ANY', 'PUT', 'GET', 'POST', 'DELETE', 'OPTIONS', 'HEAD', 'PATCH']} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['rest-integration']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.rest-resource Resource Type Implementations for {function.name}: - In :file:`c7n/resources/apigw.py` 329 .. parsed-literal:: @RestResource.filter_registry.register(rest-integration) class FilterRestIntegration Filter rest resources based on a key value for the rest method integration of the api :example: .. code-block:: yaml policies: - name: api-method-integrations-with-type-aws resource: rest-resource filters: - type: rest-integration key: type value: AWS Policies studied have 0 examples. rest-method (no examples) ------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} method: {'type': 'string', 'enum': ['all', 'ANY', 'PUT', 'GET', 'POST', 'DELETE', 'OPTIONS', 'HEAD', 'PATCH']} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['rest-method']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.rest-resource Resource Type Implementations for {function.name}: - In :file:`c7n/resources/apigw.py` 505 .. parsed-literal:: @RestResource.filter_registry.register(rest-method) class FilterRestMethod Filter rest resources based on a key value for the rest method of the api :example: .. code-block:: yaml policies: - name: api-without-key-required resource: rest-resource filters: - type: rest-method key: apiKeyRequired value: false Policies studied have 0 examples. target-group (no examples) -------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['target-group']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.app-elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/appelb.py` 826 .. parsed-literal:: @filters.register(target-group) class AppELBTargetGroupFilter Filter ALB based on matching target group value Policies studied have 0 examples. instance-attribute (no examples) -------------------------------- Schema .. code:: yaml attribute: {'enum': ['instanceType', 'kernel', 'ramdisk', 'userData', 'disableApiTermination', 'instanceInitiatedShutdownBehavior', 'rootDeviceName', 'blockDeviceMapping', 'productCodes', 'sourceDestCheck', 'groupSet', 'ebsOptimized', 'sriovNetSupport', 'enaSupport']} default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['instance-attribute']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 1686 .. parsed-literal:: @filters.register(instance-attribute) class InstanceAttribute EC2 Instance Value FIlter on a given instance attribute. Filters EC2 Instances with the given instance attribute :Example: .. code-block:: yaml policies: - name: ec2-unoptimized-ebs resource: ec2 filters: - type: instance-attribute attribute: ebsOptimized key: "Value" value: false Policies studied have 0 examples. ssm (no examples) ----------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['ssm']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 812 .. parsed-literal:: @EC2.filter_registry.register(ssm) class SsmStatus Filter ec2 instances by their ssm status information. :Example: Find ubuntu 18.04 instances are active with ssm. .. code-block:: yaml policies: - name: ec2-recover-instances resource: ec2 filters: - type: ssm key: PingStatus value: Online - type: ssm key: PlatformName value: Ubuntu - type: ssm key: PlatformVersion value: 18.04 Policies studied have 0 examples. event-source (no examples) -------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['event-source']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.lambda Resource Type Implementations for {function.name}: - In :file:`c7n/resources/awslambda.py` 206 .. parsed-literal:: @filters.register(event-source) class LambdaEventSource Policies studied have 0 examples. db-parameter (no examples) -------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['db-parameter']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.rds Resource Type Implementations for {function.name}: - In :file:`c7n/resources/rds.py` 1505 .. parsed-literal:: @filters.register(db-parameter) class ParameterFilter Applies value type filter on set db parameter values. :example: .. code-block:: yaml policies: - name: rds-pg resource: rds filters: - type: db-parameter key: someparam op: eq value: someval Policies studied have 0 examples. param (no examples) ------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['param']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.redshift Resource Type Implementations for {function.name}: - In :file:`c7n/resources/redshift.py` 131 .. parsed-literal:: @filters.register(param) class Parameter Filter redshift clusters based on parameter values :example: .. code-block:: yaml policies: - name: redshift-no-ssl resource: redshift filters: - type: param key: require_ssl value: false op: eq Policies studied have 0 examples. bucket-notification (no examples) --------------------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} kind: {'type': 'string', 'enum': ['lambda', 'sns', 'sqs']} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['bucket-notification']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 932 .. parsed-literal:: @filters.register(bucket-notification) class BucketNotificationFilter Filter based on bucket notification configuration. :example: .. code-block:: yaml policies: - name: delete-incorrect-notification resource: s3 filters: - type: bucket-notification kind: lambda key: Id value: "IncorrectLambda" op: eq actions: - type: delete-bucket-notification statement_ids: matched Policies studied have 0 examples. inventory (no examples) ----------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['inventory']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 2292 .. parsed-literal:: @filters.register(inventory) class Inventory Filter inventories for a bucket Policies studied have 0 examples. route (no examples) ------------------- Schema .. code:: yaml default: {'type': 'object'} key: {'type': 'string'} op: {'enum': ['eq', 'equal', 'ne', 'not-equal', 'gt', 'greater-than', 'ge', 'gte', 'le', 'lte', 'lt', 'less-than', 'glob', 'regex', 'in', 'ni', 'not-in', 'contains', 'difference', 'intersect']} type: {'enum': ['route']} value: {'oneOf': [{'type': 'array'}, {'type': 'string'}, {'type': 'boolean'}, {'type': 'number'}, {'type': 'null'}]} value_from: {'type': 'object', 'additionalProperties': 'False', 'required': ['url'], 'properties': {'url': {'type': 'string'}, 'format': {'enum': ['csv', 'json', 'txt', 'csv2dict']}, 'expr': {'oneOf': [{'type': 'integer'}, {'type': 'string'}]}}} value_type: {'enum': ['age', 'integer', 'expiration', 'normalize', 'size', 'cidr', 'cidr_size', 'swap', 'resource_count', 'expr', 'unique_size']} Used by aws.route-table Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 1333 .. parsed-literal:: @RouteTable.filter_registry.register(route) class Route Filter a route table by its routes' attributes. Policies studied have 0 examples. Singleton/Boolean Filters ========================= skip-ami-snapshots ------------------ Schema .. code:: yaml type: {'enum': ['skip-ami-snapshots']} value: {'type': 'boolean'} Used by aws.ebs-snapshot Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ebs.py` 237 .. parsed-literal:: @Snapshot.filter_registry.register(skip-ami-snapshots) class SnapshotSkipAmiSnapshots Filter to remove snapshots of AMIs from results This filter is 'true' by default. :example: implicit with no parameters, 'true' by default .. code-block:: yaml policies: - name: delete-stale-snapshots resource: ebs-snapshot filters: - type: age days: 28 op: ge - skip-ami-snapshots :example: explicit with parameter .. code-block:: yaml policies: - name: delete-snapshots resource: ebs-snapshot filters: - type: age days: 28 op: ge - type: skip-ami-snapshots value: false Policies studied have 86 examples. .. code:: yaml name: ebs-snapshot-untagged-delete comment: Delete any EBS snapshots whose delete date has arrived. resource: ebs-snapshot filters: - type: skip-ami-snapshots value: true - key: SnapshotId op: ni type: value value_from: expr: all.exceptions.["ebs-snapshot"][].snapshot.["SnapshotId"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:Name op: ne type: value value: REDACTED NAME - op: delete tag: custodian_tagging type: marked-for-op - or: - or: - not: - and: - or: - and: - tag:ASV: not-null - key: tag:ASV op: not-equal type: value value: '' value_type: normalize - and: - tag:BA: not-null - key: tag:BA op: not-equal type: value value: '' value_type: normalize - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - key: tag:GroupName op: not-in type: value value: - EMMO - key: tag:ApplicationName op: not-in type: value value: - EMMO-FactFinder - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - or: - tag:ApplicationName: absent - tag:Environment: absent - tag:Uptime: absent - key: tag:ApplicationName op: eq type: value value: '' value_type: normalize - key: tag:Environment op: eq type: value value: '' value_type: normalize - key: tag:Uptime op: eq type: value value: '' value_type: normalize actions: # REDACTED # .. code:: yaml name: ebs-snapshot-untagged-two-day-warning comment: Final warning for EBS snapshots marked for delete. resource: ebs-snapshot filters: - type: skip-ami-snapshots value: true - key: SnapshotId op: ni type: value value_from: expr: all.exceptions.["ebs-snapshot"][].snapshot.["SnapshotId"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:Name op: ne type: value value: REDACTED NAME - or: - and: - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - tag:OwnerEID: not-null - key: tag:OwnerEID op: not-equal type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (^[A-Za-z]{3}[0-9]{3}$) - op: delete skew: 2 tag: custodian_tagging type: marked-for-op - or: - or: - not: - and: - or: - and: - tag:ASV: not-null - key: tag:ASV op: not-equal type: value value: '' value_type: normalize - and: - tag:BA: not-null - key: tag:BA op: not-equal type: value value: '' value_type: normalize - tag:OwnerContact: not-null - key: tag:OwnerContact op: not-equal type: value value: '' value_type: normalize - and: - key: tag:GroupName op: not-in type: value value: - EMMO - key: tag:ApplicationName op: not-in type: value value: - EMMO-FactFinder - key: tag:ASV op: not-in type: value value: - ASVredacted - ASVredacted - ASVredacted - ASVredacted - ASVredacted - or: - tag:ApplicationName: absent - tag:Environment: absent - tag:Uptime: absent - key: tag:ApplicationName op: eq type: value value: '' value_type: normalize - key: tag:Environment op: eq type: value value: '' value_type: normalize - key: tag:Uptime op: eq type: value value: '' value_type: normalize actions: # REDACTED # .. code:: yaml name: ebs-snapshot-untagged-two-day-warning-no-owner comment: Final warning for EBS snapshots marked for delete. resource: ebs-snapshot filters: - type: skip-ami-snapshots value: true - key: SnapshotId op: ni type: value value_from: expr: all.exceptions.["ebs-snapshot"][].snapshot.["SnapshotId"][].*[].*[] format: json url: s3://redacted/bucket - key: tag:Name op: ne type: value value: REDACTED NAME - or: - tag:OwnerContact: absent - key: tag:OwnerContact op: eq type: value value: '' value_type: normalize - or: - tag:OwnerEID: absent - key: tag:OwnerEID op: eq type: value value: '' value_type: normalize - key: tag:OwnerEID op: regex type: value value: (?!(^[A-Za-z]{3}[0-9]{3})$) - op: delete skew: 2 tag: custodian_tagging type: marked-for-op actions: # REDACTED # missing-policy-statement ------------------------ Schema .. code:: yaml statement_ids: {'type': 'array', 'items': {'type': 'string'}} type: {'enum': ['missing-policy-statement', 'missing-statement']} Used by aws.s3 No implementation for missing-policy-statement. Policies studied have 65 examples. .. code:: yaml name: s3-encrypt-keys description: ISRM 12 - S3 nightly encrypt job for any unencrypted keys resource: s3 filters: - statement_ids: - RequireEncryptedPutObject type: missing-policy-statement actions: # REDACTED # .. code:: yaml name: s3-encrypt-keys description: ISRM 12 - S3 nightly encrypt job for any unencrypted keys resource: s3 filters: - statement_ids: - RequireEncryptedPutObject type: missing-policy-statement actions: # REDACTED # .. code:: yaml name: s3-encrypt-keys description: ISRM 12 - S3 nightly encrypt job for any unencrypted keys resource: s3 filters: - statement_ids: - RequireEncryptedPutObject type: missing-policy-statement actions: # REDACTED # ssl-policy ---------- Schema .. code:: yaml blacklist: {'type': 'array', 'items': {'type': 'string'}} matching: {'type': 'string'} type: {'enum': ['ssl-policy']} whitelist: {'type': 'array', 'items': {'type': 'string'}} Used by aws.elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/elb.py` 514 .. parsed-literal:: @filters.register(ssl-policy) class SSLPolicyFilter Filter ELBs on the properties of SSLNegotation policies. TODO: Only works on custom policies at the moment. whitelist: filter all policies containing permitted protocols blacklist: filter all policies containing forbidden protocols Cannot specify both whitelist & blacklist in the same policy. These must be done seperately (seperate policy statements). Likewise, if you want to reduce the consideration set such that we only compare certain keys (e.g. you only want to compare the `Protocol-` keys), you can use the `matching` option with a regular expression: :example: .. code-block:: yaml policies: - name: elb-ssl-policies resource: elb filters: - type: ssl-policy blacklist: - "Protocol-SSLv2" - "Protocol-SSLv3" - name: elb-modern-tls resource: elb filters: - type: ssl-policy matching: "^Protocol-" whitelist: - "Protocol-TLSv1.1" - "Protocol-TLSv1.2" Policies studied have 40 examples. .. code:: yaml name: parent-elb-ssl-require-tls12 description: ISRM 8 - HTTPS/SSL ELBs should have secure ciphers/protocols only. resource: elb filters: - key: CreatedTime op: greater-than type: value value: 0.011 value_type: age - type: ssl-policy whitelist: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - Protocol-TLSv1.2 - Server-Defined-Cipher-Order actions: # REDACTED # .. code:: yaml name: parent-elb-ssl-require-tls12-temp description: ISRM 8 - HTTPS/SSL ELBs should have secure ciphers/protocols only. resource: elb filters: - key: CreatedTime op: greater-than type: value value: 0.011 value_type: age - type: ssl-policy whitelist: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 - Protocol-TLSv1.2 - Server-Defined-Cipher-Order actions: # REDACTED # .. code:: yaml name: elb-ssl-whitelist description: ISRM 8 - HTTPS/SSL ELBs should have secure ciphers/protocols only. resource: elb filters: - type: ssl-policy whitelist: - Protocol-TLSv1.2 - Server-Defined-Cipher-Order - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 - ECDHE-ECDSA-AES256-GCM-SHA384 - ECDHE-RSA-AES256-GCM-SHA384 - DHE-RSA-AES128-GCM-SHA256 - DHE-RSA-AES256-GCM-SHA384 actions: # REDACTED # service-limit ------------- Schema .. code:: yaml limits: {'type': 'array', 'items': {'type': 'string'}} refresh_period: {'type': 'integer'} services: {'type': 'array', 'items': {'enum': ['EC2', 'ELB', 'VPC', 'AutoScaling', 'RDS', 'EBS', 'SES', 'IAM']}} threshold: {'type': 'number'} type: {'enum': ['service-limit']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 348 .. parsed-literal:: @filters.register(service-limit) class ServiceLimit Check if account's service limits are past a given threshold. Supported limits are per trusted advisor, which is variable based on usage in the account and support level enabled on the account. - service: AutoScaling limit: Auto Scaling groups - service: AutoScaling limit: Launch configurations - service: EBS limit: Active snapshots - service: EBS limit: Active volumes - service: EBS limit: General Purpose (SSD) volume storage (GiB) - service: EBS limit: Magnetic volume storage (GiB) - service: EBS limit: Provisioned IOPS - service: EBS limit: Provisioned IOPS (SSD) storage (GiB) - service: EC2 limit: Elastic IP addresses (EIPs) # Note this is extant for each active instance type in the account # however the total value is against sum of all instance types. # see issue https://github.com/capitalone/cloud-custodian/issues/516 - service: EC2 limit: On-Demand instances - m3.medium - service: EC2 limit: Reserved Instances - purchase limit (monthly) - service: ELB limit: Active load balancers - service: IAM limit: Groups - service: IAM limit: Instance profiles - service: IAM limit: Roles - service: IAM limit: Server certificates - service: IAM limit: Users - service: RDS limit: DB instances - service: RDS limit: DB parameter groups - service: RDS limit: DB security groups - service: RDS limit: DB snapshots per user - service: RDS limit: Storage quota (GB) - service: RDS limit: Internet gateways - service: SES limit: Daily sending quota - service: VPC limit: VPCs - service: VPC limit: VPC Elastic IP addresses (EIPs) :example: .. code-block:: yaml policies: - name: account-service-limits resource: account filters: - type: service-limit services: - EC2 threshold: 1.0 - name: specify-region-for-global-service region: us-east-1 resource: account filters: - type: service-limit services: - IAM limits: - Roles Policies studied have 35 examples. .. code:: yaml name: account-service-limits-notify description: Reports back to Shared Tech Operations any service limits exceeding 80% resource: account filters: - type: service-limit actions: # REDACTED # .. code:: yaml name: account-service-limits-notify description: Reports back to Shared Tech Operations any service limits exceeding 80% resource: account filters: - type: service-limit actions: # REDACTED # .. code:: yaml name: account-service-limits-notify description: Reports back to Shared Tech Operations any service limits exceeding 80% resource: account filters: - type: service-limit actions: # REDACTED # ingress ------- Schema .. code:: yaml Ports: {'type': 'array', 'items': {'type': 'integer'}} SelfReference: {'type': 'boolean'} match-operator: {'type': 'string', 'enum': ['or', 'and']} type: {'enum': ['ingress']} Used by aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 1041 .. parsed-literal:: @SecurityGroup.filter_registry.register(ingress) class IPPermission Policies studied have 32 examples. .. code:: yaml name: sg-rule-3a-public-subnet-ingress description: Notify security group in public subnet that does not comply with ingress rules resource: security-group filters: - or: - tag:NetworkLocation: PubFacing - tag:NetworkLocation: Public - Cidr: op: eq value: 0.0.0.0/0 OnlyPorts: - 80 - 443 - 8098 type: ingress actions: # REDACTED # .. code:: yaml name: sg-rule-3a-nonpublic-subnet-ingress description: Notify security group in nonpublic subnet that does not comply with ingress rules resource: security-group filters: - key: tag:NetworkLocation op: not-equal type: value value: Public - key: tag:NetworkLocation op: not-equal type: value value: PubFacing - Cidr: op: in value: - 0.0.0.0/0 - ::/0 type: ingress actions: # REDACTED # .. code:: yaml name: sg-rule-3a-public-subnet-ingress description: Notify security group in public subnet that does not comply with ingress rules resource: security-group filters: - or: - tag:NetworkLocation: PubFacing - tag:NetworkLocation: Public - Cidr: op: eq value: 0.0.0.0/0 OnlyPorts: - 80 - 443 - 8098 type: ingress actions: # REDACTED # global-grants ------------- Schema .. code:: yaml allow_website: {'type': 'boolean'} operator: {'type': 'string', 'enum': ['or', 'and']} permissions: {'type': 'array', 'items': {'type': 'string', 'enum': ['READ', 'WRITE', 'WRITE_ACP', 'READ_ACP', 'FULL_CONTROL']}} type: {'enum': ['global-grants']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 644 .. parsed-literal:: @filters.register(global-grants) class GlobalGrantsFilter Filters for all S3 buckets that have global-grants :example: .. code-block:: yaml policies: - name: s3-delete-global-grants resource: s3 filters: - type: global-grants actions: - delete-global-grants Policies studied have 25 examples. .. code:: yaml name: deny-s3-global-access resource: s3 filters: - global-grants actions: # REDACTED # .. code:: yaml name: enterprise-deny-s3-global-access comment: Check for global access to s3 buckets and report them. resource: s3 filters: - type: global-grants actions: # REDACTED # .. code:: yaml name: enterprise-deny-s3-global-access-lambda comment: Check for global access to s3 buckets and report them. resource: s3 filters: - type: global-grants actions: # REDACTED # last-write ---------- Schema .. code:: yaml days: {'type': 'number'} type: {'enum': ['last-write']} Used by aws.log-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/cw.py` 232 .. parsed-literal:: @LogGroup.filter_registry.register(last-write) class LastWriteDays Filters CloudWatch log groups by last write :example: .. code-block:: yaml policies: - name: cloudwatch-stale-groups resource: log-group filters: - type: last-write days: 60 Policies studied have 14 examples. .. code:: yaml name: log-group-thirty-day-report comments: Report on log groups that haven't been used in 30 days resource: log-group filters: - days: 30 type: last-write actions: # REDACTED # .. code:: yaml name: log-group-gc comments: Delete log groups that haven't been used in 60 days resource: log-group filters: - days: 60 type: last-write actions: # REDACTED # .. code:: yaml name: parent-cloudwatch-loggroup-notify-unused comment: Notify log groups that have not been writen to in over 55 days resource: log-group filters: - days: 55 type: last-write actions: # REDACTED # invalid ------- Schema .. code:: yaml type: {'enum': ['invalid']} Used by aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/asg.py` 372 .. parsed-literal:: @filters.register(invalid) class InvalidConfigFilter Filter autoscale groups to find those that are structurally invalid. Structurally invalid means that the auto scale group will not be able to launch an instance succesfully as the configuration has - invalid subnets - invalid security groups - invalid key pair name - invalid launch config volume snapshots - invalid amis - invalid health check elb (slower) Internally this tries to reuse other resource managers for better cache utilization. :example: .. code-base: yaml policies: - name: asg-invalid-config resource: asg filters: - invalid Policies studied have 11 examples. .. code:: yaml name: asg-invalid-check comment: Any ASGs which are now invalid (invalid subnets, invalid launch config volume snapshots, invalid amis, invalid health check elb, invalid key pair name, invalid ami) should be marked resource: asg filters: - tag:custodian_invalid_asg: absent - tag:OwnerContact: not-null - invalid actions: # REDACTED # .. code:: yaml name: asg-invalid-check-no-ownercontact comment: Any ASGs which are now invalid (invalid subnets, invalid launch config volume snapshots, invalid amis, invalid health check elb, invalid key pair name, invalid ami) should be marked resource: asg filters: - tag:custodian_invalid_asg: absent - tag:OwnerContact: absent - invalid actions: # REDACTED # .. code:: yaml name: asg-invalid-check comment: Any ASGs which are now invalid (invalid subnets, invalid launch config volume snapshots, invalid amis, invalid health check elb, invalid key pair name, invalid ami) should be marked resource: asg filters: - tag:custodian_invalid_asg: absent - tag:OwnerContact: not-null - invalid actions: # REDACTED # not-encrypted ------------- Schema .. code:: yaml exclude_image: {'type': 'boolean'} type: {'enum': ['not-encrypted']} Used by aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/asg.py` 408 .. parsed-literal:: @filters.register(not-encrypted) class NotEncryptedFilter Check if an ASG is configured to have unencrypted volumes. Checks both the ami snapshots and the launch configuration. :example: .. code-block:: yaml policies: - name: asg-unencrypted resource: asg filters: - type: not-encrypted exclude_image: true Policies studied have 7 examples. .. code:: yaml name: asg-existing-non-encrypted resource: asg filters: - not-encrypted actions: # REDACTED # .. code:: yaml name: enterprise-asg-unencrypted-delete description: Require EBS encryption for all newly provisioned ASGs. resource: asg filters: - type: not-encrypted actions: # REDACTED # .. code:: yaml name: enterprise-asg-unencrypted-delete-existing description: Require EBS encryption for all existing provisioned ASGs. resource: asg filters: - type: not-encrypted actions: # REDACTED # is-log-target ------------- Schema .. code:: yaml self: {'type': 'boolean'} services: {'type': 'array', 'items': {'enum': ['s3', 'elb', 'cloudtrail']}} type: {'enum': ['is-log-target']} value: {'type': 'boolean'} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 1954 .. parsed-literal:: @filters.register(is-log-target) class LogTarget Filter and return buckets are log destinations. Not suitable for use in lambda on large accounts, This is a api heavy process to detect scan all possible log sources. Sources: - elb (Access Log) - s3 (Access Log) - cfn (Template writes) - cloudtrail :example: .. code-block:: yaml policies: - name: s3-log-bucket resource: s3 filters: - type: is-log-target Policies studied have 7 examples. .. code:: yaml name: s3-self-loggging-buckets resource: s3 filters: - self: true type: is-log-target - key: Name op: regex type: value value: (?!cf-templates-.*|.*cloudformation.*|ent.*s3-access-logs-us.*|ent.*elb-access-logs-us.*|elasticbeanstalk-us.*|.*cloud-maid.*) actions: # REDACTED # .. code:: yaml name: s3-self-loggging-buckets resource: s3 filters: - self: true type: is-log-target - key: Name op: regex type: value value: (?!cf-templates-.*|.*cloudformation.*|ent.*s3-access-logs-us.*|ent.*elb-access-logs-us.*|elasticbeanstalk-us.*|.*cloud-maid.*) actions: # REDACTED # .. code:: yaml name: parent-s3-self-loggging-buckets resource: s3 filters: - self: true type: is-log-target - key: Name op: regex type: value value: (?!cf-templates-.*|.*cloudformation.*|ent.*s3-access-logs-us.*|ent.*elb-access-logs-us.*|elasticbeanstalk-us.*|.*cloud-maid.*) actions: # REDACTED # has-statement ------------- Schema .. code:: yaml statement_ids: {'type': 'array', 'items': {'type': 'string'}} statements: {'type': 'array', 'items': {'type': 'object', 'properties': {'Sid': {'type': 'string'}, 'Effect': {'type': 'string', 'enum': ['Allow', 'Deny']}, 'Principal': {'anyOf': [{'type': 'string'}, {'type': 'object'}, {'type': 'array'}]}, 'NotPrincipal': {'anyOf': [{'type': 'object'}, {'type': 'array'}]}, 'Action': {'anyOf': [{'type': 'string'}, {'type': 'array'}]}, 'NotAction': {'anyOf': [{'type': 'string'}, {'type': 'array'}]}, 'Resource': {'anyOf': [{'type': 'string'}, {'type': 'array'}]}, 'NotResource': {'anyOf': [{'type': 'string'}, {'type': 'array'}]}, 'Condition': {'type': 'object'}}, 'required': ['Effect']}} type: {'enum': ['has-statement']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 748 .. parsed-literal:: @filters.register(has-statement) class HasStatementFilter Find buckets with set of policy statements. :example: .. code-block:: yaml policies: - name: s3-bucket-has-statement resource: s3 filters: - type: has-statement statement_ids: - RequiredEncryptedPutObject policies: - name: s3-public-policy resource: s3 filters: - type: has-statement statements: - Effect: Allow Action: 's3:*' Principal: '*' Policies studied have 6 examples. .. code:: yaml name: s3-unmark-updated-buckets description: if the bucket has a compliant policy, unmark the bucket resource: s3 filters: - tag:c7n_s3_policy_required: present - and: - statements: - Action: s3:* Effect: Deny Principal: '*' type: has-statement - key: Policy op: contains type: value value: o-rhymjmbbe2 - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - statements: - Action: s3:* Condition: Bool: aws:SecureTransport: 'false' Effect: Deny Principal: '*' type: has-statement actions: # REDACTED # .. code:: yaml name: s3-invalid-creation-fixed-hourly description: Delete specific tag on S3 buckets that have been corrected adhering to RDT S3 template. resource: s3 filters: - statement_ids: - RequireSSLAccessRDT type: has-statement - tag:custodian_s3_ns_template: not-null actions: # REDACTED # .. code:: yaml name: enterprise-s3-unmark-updated-buckets description: if the bucket has a compliant policy, unmark the bucket resource: s3 filters: - tag:c7n_s3_policy_required: present - and: - statements: - Action: s3:* Effect: Deny Principal: '*' type: has-statement - key: Policy op: contains type: value value: o-rhymjmbbe2 - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - key: Policy op: contains type: value value: arn:aws:sts::{account_id}:assumed-role/Redacted/* - statements: - Action: s3:* Condition: Bool: aws:SecureTransport: 'false' Effect: Deny Principal: '*' type: has-statement actions: # REDACTED # missing ------- Schema .. code:: yaml policy: {'type': 'object'} type: {'enum': ['missing']} Used by aws.account No implementation for missing. Policies studied have 5 examples. .. code:: yaml name: azure-policy-sqlserverauditing-enable comments: Ensure that SQL auditing is enabled. This custodian policy checks to see if auditing is enabled at the server level. If not, it applies an azure policy which will enable auditing resource: azure.subscription filters: - policy: filters: - key: properties.displayName op: eq type: value value: Audit SQL server level Auditing settings resource: azure.policyassignments type: missing actions: # REDACTED # .. code:: yaml name: azure-policy-deny-byol-enable comments: Ensure that denial of bring your own license azure policy enabled. If not, it applies the azure policy which will enable auditing. resource: azure.subscription filters: - policy: filters: - key: properties.displayName op: eq type: value value: azr-ctl-vm-002 resource: azure.policyassignments type: missing actions: # REDACTED # .. code:: yaml name: azure-policy-allowed-resources-enable comments: Ensure that allowed resources azure policy enabled. If not, it applies the azure policy which will enable auditing. resource: azure.subscription filters: - policy: filters: - key: properties.displayName op: eq type: value value: azr-ctl-core-002 resource: azure.policyassignments type: missing actions: # REDACTED # mismatch-s3-origin ------------------ Schema .. code:: yaml check_custom_origins: {'type': 'boolean'} type: {'enum': ['mismatch-s3-origin']} Used by aws.distribution Resource Type Implementations for {function.name}: - In :file:`c7n/resources/cloudfront.py` 183 .. parsed-literal:: @Distribution.filter_registry.register(mismatch-s3-origin) class MismatchS3Origin Check for existence of S3 bucket referenced by Cloudfront, and verify whether owner is different from Cloudfront account owner. :example: .. code-block:: yaml policies: - name: mismatch-s3-origin resource: distribution filters: - type: mismatch-s3-origin check_custom_origins: true Policies studied have 5 examples. .. code:: yaml name: enterprise-distribution-with-missing-or-mismatched-origin description: Identify CloudFront Distributions with non-existant S3 Origins or Origins that are owned by a different account than the CF Distribution. resource: distribution filters: - check_custom_origins: true type: mismatch-s3-origin actions: # REDACTED # .. code:: yaml name: enterprise-distribution-with-missing-or-mismatched-origin description: Identify CloudFront Distributions with non-existant S3 Origins or Origins that are owned by a different account than the CF Distribution. resource: distribution filters: - check_custom_origins: true type: mismatch-s3-origin actions: # REDACTED # .. code:: yaml name: enterprise-distribution-with-missing-or-mismatched-origin description: Identify CloudFront Distributions with non-existant S3 Origins or Origins that are owned by a different account than the CF Distribution. resource: distribution filters: - check_custom_origins: true type: mismatch-s3-origin actions: # REDACTED # egress ------ Schema .. code:: yaml SelfReference: {'type': 'boolean'} match-operator: {'type': 'string', 'enum': ['or', 'and']} type: {'enum': ['egress']} Used by aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 1057 .. parsed-literal:: @SecurityGroup.filter_registry.register(egress) class IPPermissionEgress Policies studied have 5 examples. .. code:: yaml name: sg-rule-egress-notify description: Notify security group that does not comply with egress rules resource: security-group filters: - Cidr: op: in value: - 0.0.0.0/0 - ::/0 type: egress actions: # REDACTED # .. code:: yaml name: sg-rule-egress-notify description: Notify security group that does not comply with egress rules resource: security-group filters: - Cidr: op: in value: - 0.0.0.0/0 - ::/0 type: egress actions: # REDACTED # .. code:: yaml name: sg-rule-3a-nonpublic-egress-mark description: 0.0.0.0/0 egress is not allowed resource: security-group filters: - tag:egress_violation: absent - Cidr: op: in value: - 0.0.0.0/0 - ::/0 type: egress actions: # REDACTED # valid ----- Schema .. code:: yaml type: {'enum': ['valid']} Used by aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/asg.py` 345 .. parsed-literal:: @filters.register(valid) class ValidConfigFilter Filters autoscale groups to find those that are structurally valid. This operates as the inverse of the invalid filter for multi-step workflows. See details on the invalid filter for a list of checks made. :example: .. code-base: yaml policies: - name: asg-valid-config resource: asg filters: - valid Policies studied have 4 examples. .. code:: yaml name: asg-valid-check comment: Any ASGs which are now valid should be unmarked resource: asg filters: - tag:custodian_invalid_asg: not-null - valid actions: # REDACTED # .. code:: yaml name: asg-valid-check comment: Any ASGs which are now valid should be unmarked resource: asg filters: - tag:custodian_invalid_asg: not-null - valid actions: # REDACTED # .. code:: yaml name: asg-valid-check comment: Any ASGs which are now valid should be unmarked resource: asg filters: - tag:custodian_invalid_asg: not-null - valid actions: # REDACTED # latest ------ Schema .. code:: yaml automatic: {'type': 'boolean'} type: {'enum': ['latest']} Used by aws.rds-snapshot Resource Type Implementations for {function.name}: - In :file:`c7n/resources/rds.py` 1026 .. parsed-literal:: @RDSSnapshot.filter_registry.register(latest) class LatestSnapshot Return the latest snapshot for each database. Policies studied have 3 examples. .. code:: yaml name: rds-snapshot-region-copy resource: rds-snapshot filters: - tag:CrossRegionTransfer: present - latest - key: AllocatedStorage op: lte type: value value: 250 actions: # REDACTED # .. code:: yaml name: rds-snapshot-region-copy-daily description: Copy RDS snapshots from east region to west region resource: rds-snapshot filters: - tag:CrossRegionTransfer: present - latest - key: AllocatedStorage op: lte type: value value: 100 actions: # REDACTED # .. code:: yaml name: rds-snapshot-region-copy-daily description: Copy RDS snapshots from east region to west region resource: rds-snapshot filters: - tag:CrossRegionTransfer: present - latest - key: AllocatedStorage op: lte type: value value: 100 actions: # REDACTED # capacity-delta -------------- Schema .. code:: yaml type: {'enum': ['capacity-delta']} Used by aws.asg Resource Type Implementations for {function.name}: - In :file:`c7n/resources/asg.py` 806 .. parsed-literal:: @filters.register(capacity-delta) class CapacityDelta Filter returns ASG that have less instances than desired or required :example: .. code-block:: yaml policies: - name: asg-capacity-delta resource: asg filters: - capacity-delta Policies studied have 2 examples. .. code:: yaml name: asg-invalid-report-daily description: Mark ASGs that are spinning (attempting and failing to launch instances repeatedly) and mark them for deletion in 3 days resource: asg filters: - tag:custodian_invalid: absent - invalid - capacity-delta actions: # REDACTED # .. code:: yaml name: asg-invalid-delete-daily description: Delete ASGs that are spinning (attempting and failing to launch instances repeatedly resource: asg filters: - op: delete tag: custodian_invalid type: marked-for-op - key: tag:CMDBEnvironment op: ni type: value value_from: expr: exemptions.*[].ami.*[].["tag:CMDBEnvironment"][][] format: json url: s3://redacted/bucket - key: tag:ASV op: ni type: value value_from: expr: exemptions.*[].ami.*[].["tag:ASV"][][] format: json url: s3://redacted/bucket - invalid - capacity-delta actions: # REDACTED # check-cloudtrail ---------------- Schema .. code:: yaml current-region: {'type': 'boolean'} file-digest: {'type': 'boolean'} global-events: {'type': 'boolean'} kms: {'type': 'boolean'} kms-key: {'type': 'string'} multi-region: {'type': 'boolean'} notifies: {'type': 'boolean'} running: {'type': 'boolean'} type: {'enum': ['check-cloudtrail']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 98 .. parsed-literal:: @filters.register(check-cloudtrail) class CloudTrailEnabled Verify cloud trail enabled for this account per specifications. Returns an annotated account resource if trail is not enabled. Of particular note, the current-region option will evaluate whether cloudtrail is available in the current region, either as a multi region trail or as a trail with it as the home region. :example: .. code-block:: yaml policies: - name: account-cloudtrail-enabled resource: account region: us-east-1 filters: - type: check-cloudtrail global-events: true multi-region: true running: true Policies studied have 1 examples. .. code:: yaml name: aws-cloudtrail-not-enabled comment: Policy scans for accounts which do not have CloudTrails enabled in the current region resource: account filters: - global-events: true multi-region: true running: true type: check-cloudtrail actions: # REDACTED # check-config ------------ Schema .. code:: yaml all-resources: {'type': 'boolean'} global-resources: {'type': 'boolean'} running: {'type': 'boolean'} type: {'enum': ['check-config']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 171 .. parsed-literal:: @filters.register(check-config) class ConfigEnabled Is config service enabled for this account :example: .. code-block:: yaml policies: - name: account-check-config-services resource: account region: us-east-1 filters: - type: check-config all-resources: true global-resources: true running: true Policies studied have 1 examples. .. code:: yaml name: aws-config-not-enabled comment: Policy scans for accounts which do not have the AWS config service enabled resource: account filters: - all-resources: true global-resources: true running: true type: check-config actions: # REDACTED # grant-count ----------- Schema .. code:: yaml min: {'type': 'integer', 'minimum': 0} type: {'enum': ['grant-count']} Used by aws.kms Resource Type Implementations for {function.name}: - In :file:`c7n/resources/kms.py` 162 .. parsed-literal:: @KeyAlias.filter_registry.register(grant-count) class GrantCount Filters KMS key grants This can be used to ensure issues around grant limits are monitored :example: .. code-block:: yaml policies: - name: kms-grants resource: kms filters: - type: grant-count min: 100 Policies studied have 1 examples. .. code:: yaml name: kms-extant-grants-reporting comment: Monitor kms keys with more than 100 extant keys. This allows us to setup cloudwatch alerts on the grant limits to ensure we don't end up in a situation where we can't allocate instances or volumes due to hitting max limits on kms grants resource: kms filters: - min: 100 type: grant-count actions: # REDACTED # has-users (no examples) ----------------------- Schema .. code:: yaml type: {'enum': ['has-users']} value: {'type': 'boolean'} Used by aws.iam-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 1584 .. parsed-literal:: @Group.filter_registry.register(has-users) class IamGroupUsers Filter IAM groups that have users attached based on True/False value: True: Filter all IAM groups with users assigned to it False: Filter all IAM groups without any users assigned to it :example: .. code-block:: yaml - name: empty-iam-group resource: iam-group filters: - type: has-users value: False Policies studied have 0 examples. has-specific-managed-policy (no examples) ----------------------------------------- Schema .. code:: yaml type: {'enum': ['has-specific-managed-policy']} value: {'type': 'string'} Used by aws.iam-role Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 453 .. parsed-literal:: @Role.filter_registry.register(has-specific-managed-policy) class SpecificIamRoleManagedPolicy Filter IAM roles that has a specific policy attached For example, if the user wants to check all roles with 'admin-policy': :example: .. code-block:: yaml policies: - name: iam-roles-have-admin resource: iam-role filters: - type: has-specific-managed-policy value: admin-policy Policies studied have 0 examples. no-specific-managed-policy (no examples) ---------------------------------------- Schema .. code:: yaml type: {'enum': ['no-specific-managed-policy']} value: {'type': 'string'} Used by aws.iam-role Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 485 .. parsed-literal:: @Role.filter_registry.register(no-specific-managed-policy) class NoSpecificIamRoleManagedPolicy Filter IAM roles that do not have a specific policy attached For example, if the user wants to check all roles without 'ip-restriction': :example: .. code-block:: yaml policies: - name: iam-roles-no-ip-restriction resource: iam-role filters: - type: no-specific-managed-policy value: ip-restriction Policies studied have 0 examples. has-allow-all (no examples) --------------------------- Schema .. code:: yaml type: {'enum': ['has-allow-all']} Used by aws.iam-policy Resource Type Implementations for {function.name}: - In :file:`c7n/resources/iam.py` 619 .. parsed-literal:: @Policy.filter_registry.register(has-allow-all) class AllowAllIamPolicies Check if IAM policy resource(s) have allow-all IAM policy statement block. This allows users to implement CIS AWS check 1.24 which states that no policy must exist with the following requirements. Policy must have 'Action' and Resource = '*' with 'Effect' = 'Allow' The policy will trigger on the following IAM policy (statement). For example: .. code-block:: json { "Version": "2012-10-17", "Statement": [{ "Action": "*", "Resource": "*", "Effect": "Allow" }] } Additionally, the policy checks if the statement has no 'Condition' or 'NotAction' For example, if the user wants to check all used policies and filter on allow all: .. code-block:: yaml - name: iam-no-used-all-all-policy resource: iam-policy filters: - type: used - type: has-allow-all Note that scanning and getting all policies and all statements can take a while. Use it sparingly or combine it with filters such as 'used' as above. Policies studied have 0 examples. has-virtual-mfa (no examples) ----------------------------- Schema .. code:: yaml type: {'enum': ['has-virtual-mfa']} value: {'type': 'boolean'} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 739 .. parsed-literal:: @filters.register(has-virtual-mfa) class HasVirtualMFA Is the account configured with a virtual MFA device? :example: .. code-block:: yaml policies: - name: account-with-virtual-mfa resource: account region: us-east-1 filters: - type: has-virtual-mfa value: true Policies studied have 0 examples. xray-encrypt-key (no examples) ------------------------------ Schema .. code:: yaml key: {'type': 'string'} type: {'enum': ['xray-encrypt-key']} Used by aws.account Resource Type Implementations for {function.name}: - In :file:`c7n/resources/account.py` 988 .. parsed-literal:: @filters.register(xray-encrypt-key) class XrayEncrypted Determine if xray is encrypted. :example: .. code-block:: yaml policies: - name: xray-encrypt-with-default resource: aws.account filters: - type: xray-encrypt-key key: default - name: xray-encrypt-with-kms - type: xray-encrypt-key key: kms - name: xray-encrypt-with-specific-key -type: xray-encrypt-key key: alias/my-alias or arn or keyid Policies studied have 0 examples. ephemeral (no examples) ----------------------- Schema .. code:: yaml type: {'enum': ['ephemeral']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 569 .. parsed-literal:: @filters.register(ephemeral) class EphemeralInstanceFilter EC2 instances with ephemeral storage Filters EC2 instances that have ephemeral storage (an instance-store backed root device) :Example: .. code-block:: yaml policies: - name: ec2-ephemeral-instances resource: ec2 filters: - type: ephemeral http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html Policies studied have 0 examples. singleton (no examples) ----------------------- Schema .. code:: yaml type: {'enum': ['singleton']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 744 .. parsed-literal:: @filters.register(singleton) class SingletonFilter EC2 instances without autoscaling or a recover alarm Filters EC2 instances that are not members of an autoscaling group and do not have Cloudwatch recover alarms. :Example: .. code-block:: yaml policies: - name: ec2-recover-instances resource: ec2 filters: - singleton actions: - type: tag key: problem value: instance is not resilient https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-recover.html Policies studied have 0 examples. termination-protected (no examples) ----------------------------------- Schema .. code:: yaml type: {'enum': ['termination-protected']} Used by aws.ec2 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ec2.py` 313 .. parsed-literal:: @filters.register(termination-protected) class DisableApiTermination EC2 instances with ``disableApiTermination`` attribute set Filters EC2 instances with ``disableApiTermination`` attribute set to true. :Example: .. code-block:: yaml policies: - name: termination-protection-enabled resource: ec2 filters: - type: termination-protected :Example: .. code-block:: yaml policies: - name: termination-protection-NOT-enabled resource: ec2 filters: - not: - type: termination-protected Policies studied have 0 examples. progagated-tags (no examples) ----------------------------- Schema .. code:: yaml keys: {'type': 'array', 'items': {'type': 'string'}} match: {'type': 'boolean'} propagate: {'type': 'boolean'} type: {'enum': ['progagated-tags', 'propagated-tags']} Used by aws.asg No implementation for progagated-tags. Policies studied have 0 examples. is-shadow (no examples) ----------------------- Schema .. code:: yaml state: {'type': 'boolean'} type: {'enum': ['is-shadow']} Used by aws.cloudtrail Resource Type Implementations for {function.name}: - In :file:`c7n/resources/cloudtrail.py` 45 .. parsed-literal:: @CloudTrail.filter_registry.register(is-shadow) class IsShadow Identify shadow trails (secondary copies), shadow trails can't be modified directly, the origin trail needs to be modified. Shadow trails are created for multi-region trails as well for organizational trails. Policies studied have 0 examples. fault-tolerant (no examples) ---------------------------- Schema .. code:: yaml tolerant: {'type': 'boolean'} type: {'enum': ['fault-tolerant']} Used by aws.ebs Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ebs.py` 556 .. parsed-literal:: @filters.register(fault-tolerant) class FaultTolerantSnapshots This filter will return any EBS volume that does/does not have a snapshot within the last 7 days. 'Fault-Tolerance' in this instance means that, in the event of a failure, the volume can be restored from a snapshot with (reasonable) data loss - name: ebs-volume-tolerance - resource: ebs - filters: [{ 'type': 'fault-tolerant', 'tolerant': True}] Policies studied have 0 examples. modifyable (no examples) ------------------------ Schema .. code:: yaml type: {'enum': ['modifyable']} Used by aws.ebs Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ebs.py` 1144 .. parsed-literal:: @filters.register(modifyable) class ModifyableVolume Check if an ebs volume is modifyable online. Considerations - https://goo.gl/CBhfqV Consideration Summary - only current instance types are supported (one exception m3.medium) Current Generation Instances (2017-2) https://goo.gl/iuNjPZ - older magnetic volume types are not supported - shrinking volumes is not supported - must wait at least 6hrs between modifications to the same volume. - volumes must have been attached after nov 1st, 2016. See `custodian schema ebs.actions.modify` for examples. Policies studied have 0 examples. lifecycle-rule (no examples) ---------------------------- Schema .. code:: yaml match: {'type': 'array', 'items': {'oneOf': [{'$ref': '#/definitions/filters/value'}, {'type': 'object', 'minProperties': 1, 'maxProperties': 1}]}} state: {'type': 'boolean'} type: {'enum': ['lifecycle-rule']} Used by aws.ecr Resource Type Implementations for {function.name}: - In :file:`c7n/resources/ecr.py` 132 .. parsed-literal:: @ECR.filter_registry.register(lifecycle-rule) class LifecycleRule Lifecycle rule filtering :Example: .. code-block:: yaml policies: - name: ecr-life resource: aws.ecr filters: - type: lifecycle-rule state: false match: - selection.tagStatus: untagged - action.type: expire - key: selection.countNumber value: 30 op: less-than Policies studied have 0 examples. is-ssl (no examples) -------------------- Schema .. code:: yaml type: {'enum': ['is-ssl']} Used by aws.elb Resource Type Implementations for {function.name}: - In :file:`c7n/resources/elb.py` 493 .. parsed-literal:: @filters.register(is-ssl) class IsSSLFilter Filters ELB that are using a SSL policy :example: .. code-block:: yaml policies: - name: elb-using-ssl resource: elb filters: - type: is-ssl Policies studied have 0 examples. upgrade-available (no examples) ------------------------------- Schema .. code:: yaml major: {'type': 'boolean'} type: {'enum': ['upgrade-available']} value: {'type': 'boolean'} Used by aws.rds Resource Type Implementations for {function.name}: - In :file:`c7n/resources/rds.py` 364 .. parsed-literal:: @filters.register(upgrade-available) class UpgradeAvailable Scan DB instances for available engine upgrades This will pull DB instances & check their specific engine for any engine version with higher release numbers than the current one This will also annotate the rds instance with 'target_engine' which is the most recent version of the engine available :example: .. code-block:: yaml policies: - name: rds-upgrade-available resource: rds filters: - upgrade-available major: false Policies studied have 0 examples. query-logging-enabled (no examples) ----------------------------------- Schema .. code:: yaml state: {'type': 'boolean'} type: {'enum': ['query-logging-enabled']} Used by aws.hostedzone Resource Type Implementations for {function.name}: - In :file:`c7n/resources/route53.py` 412 .. parsed-literal:: @HostedZone.filter_registry.register(query-logging-enabled) class IsQueryLoggingEnabled Policies studied have 0 examples. bucket-encryption (no examples) ------------------------------- Schema .. code:: yaml crypto: {'type': 'string', 'enum': ['AES256', 'aws:kms']} key: {'type': 'string'} state: {'type': 'boolean'} type: {'enum': ['bucket-encryption']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 2788 .. parsed-literal:: @filters.register(bucket-encryption) class BucketEncryption Filters for S3 buckets that have bucket-encryption :example .. code-block:: yaml policies: - name: s3-bucket-encryption-AES256 resource: s3 region: us-east-1 filters: - type: bucket-encryption state: True crypto: AES256 - name: s3-bucket-encryption-KMS resource: s3 region: us-east-1 filters - type: bucket-encryption state: True crypto: aws:kms key: alias/some/alias/key - name: s3-bucket-encryption-off resource: s3 region: us-east-1 filters - type: bucket-encryption state: False Policies studied have 0 examples. data-events (no examples) ------------------------- Schema .. code:: yaml state: {'enum': ['present', 'absent']} type: {'enum': ['data-events']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 2242 .. parsed-literal:: @filters.register(data-events) class DataEvents Policies studied have 0 examples. no-encryption-statement (no examples) ------------------------------------- Schema .. code:: yaml type: {'enum': ['no-encryption-statement']} Used by aws.s3 Resource Type Implementations for {function.name}: - In :file:`c7n/resources/s3.py` 845 .. parsed-literal:: @filters.register(no-encryption-statement) class EncryptionEnabledFilter Find buckets with missing encryption policy statements. :example: .. code-block:: yaml policies: - name: s3-bucket-not-encrypted resource: s3 filters: - type: no-encryption-statement Policies studied have 0 examples. dhcp-options (no examples) -------------------------- Schema .. code:: yaml domain-name: {'oneOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'string'}]} domain-name-servers: {'oneOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'string'}]} ntp-servers: {'oneOf': [{'type': 'array', 'items': {'type': 'string'}}, {'type': 'string'}]} present: {'type': 'boolean'} type: {'enum': ['dhcp-options']} Used by aws.vpc Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 262 .. parsed-literal:: @Vpc.filter_registry.register(dhcp-options) class DhcpOptionsFilter Filter VPCs based on their dhcp options :example: .. code-block: yaml - policies: - name: vpcs-in-domain resource: vpc filters: - type: dhcp-options domain-name: ec2.internal if an option value is specified as a list, then all elements must be present. if an option value is specified as a string, then that string must be present. vpcs not matching a given option value can be found via specifying a `present: false` parameter. Policies studied have 0 examples. vpc-attributes (no examples) ---------------------------- Schema .. code:: yaml dnshostnames: {'type': 'boolean'} dnssupport: {'type': 'boolean'} type: {'enum': ['vpc-attributes']} Used by aws.vpc Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 212 .. parsed-literal:: @Vpc.filter_registry.register(vpc-attributes) class AttributesFilter Filters VPCs based on their DNS attributes :example: .. code-block:: yaml policies: - name: dns-hostname-enabled resource: vpc filters: - type: vpc-attributes dnshostnames: True Policies studied have 0 examples. diff (no examples) ------------------ Schema .. code:: yaml selector: {'enum': ['previous', 'date', 'locked']} selector_value: {'type': 'string'} type: {'enum': ['diff']} Used by aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 409 .. parsed-literal:: @SecurityGroup.filter_registry.register(diff) class SecurityGroupDiffFilter Policies studied have 0 examples. locked (no examples) -------------------- Schema .. code:: yaml endpoint: {'type': 'string'} region: {'type': 'string'} role: {'type': 'string'} type: {'enum': ['locked']} Used by aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 402 .. parsed-literal:: @SecurityGroup.filter_registry.register(locked) class SecurityGroupLockedFilter Policies studied have 0 examples. stale (no examples) ------------------- Schema .. code:: yaml type: {'enum': ['stale']} Used by aws.security-group Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 720 .. parsed-literal:: @SecurityGroup.filter_registry.register(stale) class Stale Filter to find security groups that contain stale references to other groups that are either no longer present or traverse a broken vpc peering connection. Note this applies to VPC Security groups only and will implicitly filter security groups. AWS Docs - https://goo.gl/nSj7VG :example: .. code-block:: yaml policies: - name: stale-security-groups resource: security-group filters: - stale Policies studied have 0 examples. missing-route (no examples) --------------------------- Schema .. code:: yaml type: {'enum': ['missing-route']} Used by aws.peering-connection Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 1437 .. parsed-literal:: @PeeringConnection.filter_registry.register(missing-route) class MissingRoute Return peers which are missing a route in route tables. If the peering connection is between two vpcs in the same account, the connection is returned unless it is in present route tables in each vpc. If the peering connection is between accounts, then the local vpc's route table is checked. Policies studied have 0 examples. s3-cidr (no examples) --------------------- Schema .. code:: yaml egress: {'type': 'boolean', 'default': True} ingress: {'type': 'boolean', 'default': True} present: {'type': 'boolean', 'default': False} type: {'enum': ['s3-cidr']} Used by aws.network-acl Resource Type Implementations for {function.name}: - In :file:`c7n/resources/vpc.py` 1513 .. parsed-literal:: @NetworkAcl.filter_registry.register(s3-cidr) class AclAwsS3Cidrs Filter network acls by those that allow access to s3 cidrs. Defaults to filtering those nacls that do not allow s3 communication. :example: Find all nacls that do not allow communication with s3. .. code-block:: yaml policies: - name: s3-not-allowed-nacl resource: network-acl filters: - s3-cidr Policies studied have 0 examples. Summary ======= .. csv-table:: :header: category, count "('Common', 'Non-Bool')",21 "('Common', 'Boolean')",15 "('Singleton', 'Non-Bool')",27 "('Singleton', 'Boolean')",47