Example offhours policy

Resource Scheduling Offhours

Custodian provides for time based filters, that allow for taking periodic action on a resource, with resource schedule customization based on tag values. A common use is offhours scheduling for asgs and instances.

Features

  • Flexible offhours scheduling with opt-in, opt-out selection, and timezone support.

  • Resume during offhours support.

  • Can be combined with other filters to get a particular set ( resources with tag, vpc, etc).

  • Can be combined with arbitrary actions

  • Can omit a set of dates such as public holidays.

Policy Configuration

We provide an onhour and offhour time filter, each should be used in a different policy, they support the same configuration options:

  • weekends: default true, whether to leave resources off for the weekend

  • weekends-only: default false, whether to turn the resource off only on the weekend

  • default_tz: which timezone to utilize when evaluating time (REQUIRED)

  • fallback-schedule: If a resource doesn’t support tagging or doesn’t provide a tag you can supply a default schedule that will be used. When the tag is provided this will be ignored. See ScheduleParser Time Specifications.

  • tag: which resource tag name to use for per-resource configuration (schedule and timezone overrides and opt-in/opt-out); default is maid_offhours.

  • 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.

  • onhour: the default time to start/run resources, specified as 0-23

  • offhour: the default time to stop/suspend resources, specified as 0-23

  • skip-days: a list of dates to skip. Dates must use format YYYY-MM-DD

  • 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.

This example policy overrides most of the defaults for an offhour policy:

policies:
  - name: offhours-stop
    resource: ec2
    filters:
      - type: offhour
        weekends: false
        default_tz: pt
        tag: downtime
        opt-out: true
        onhour: 8
        offhour: 20

Tag Based Configuration

Resources can use a special tag to override the default configuration on a per-resource basis. Note that the name of the tag is configurable via the tag option in the policy; the examples below use the default tag name, maid_offhours.

The value of the tag must be one of the following:

  • (empty) or on - An empty tag value or a value of “on” implies night and weekend offhours using the default time zone configured in the policy (tz=est if unspecified) and the default onhour and offhour values configured in the policy.

  • off - If offhours is configured to run in opt-out mode, this tag can be specified to disable offhours on a given instance. If offhours is configured to run in opt-in mode, this tag will have no effect (the resource will still be opted out).

  • a semicolon-separated string composed of one or more of the following components, which override the defaults specified in the policy:

    • tz=<timezone> to evaluate with a resource-specific timezone, where <timezone> is either one of the supported timezone aliases defined in 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 c7n.filters.offhours.ScheduleParser as described in the next section.

ScheduleParser Time Specifications

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)].

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

Possible values:

field

values

days

M, T, W, H, F, S, U

hours

0, 1, 2, …, 22, 23

Days can be specified in a range (ex. M-F).

Policy examples

Turn ec2 instances on and off

policies:
  - name: offhours-stop
    resource: ec2
    filters:
       - type: offhour
    actions:
      - stop

  - name: offhours-start
    resource: ec2
    filters:
      - type: onhour
    actions:
      - start

Here’s doing the same with auto scale groups

policies:
  - name: asg-offhours-stop
    resource: asg
    filters:
       - offhour
    actions:
       - suspend
  - name: asg-onhours-start
    resource: asg
    filters:
       - onhour
    actions:
       - resume

Additional policy examples and resource-type-specific information can be seen in the EC2 Offhours and ASG Offhours use cases.

Resume During Offhours

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 other words, if a resource has an offhours policy of stopping/suspending at 23:00 Eastern daily and starting/resuming at 06:00 Eastern daily, and you run cloud-custodian once an hour via Lambda, that resource will only be stopped once a day sometime between 23:00 and 23:59, and will only be started once a day sometime between 06:00 and 06:59. If the current hour does not exactly match the hour specified in the policy, nothing will be done at all.

As a result of this, if custodian stops an instance or suspends an ASG and you need to start/resume it, you can safely do so manually and custodian won’t touch it again until the next day.

ElasticBeanstalk, EFS and Other Services with Tag Value Restrictions

A number of AWS services have restrictions on the characters that can be used in tag values, such as ElasticBeanstalk and EFS. In particular, these services do not allow parenthesis, square brackets, commas, or semicolons, or empty tag values. This proves to be problematic with the tag-based schedule configuration described above. The best current workaround is to define a separate policy with a unique tag name for each unique schedule that you want to use, and then tag resources with that tag name and a value of on. Note that this can only be used in opt-in mode, not opt-out.

Another option is to escape the tag value with the following mapping, generated with the char’s unicode number “u” + hex(ord(the_char))[2:]. This works for GCP resources as well.

  • ( and ) as u28 and u29

  • [ and ] as u5b and u5d

  • , as u2c

  • ; as u3b

  • = as u3d

  • / as u2f

    • as u2d

Examples:

# off=(M-F,18);tz=Australia/Sydney
offu3du28M-Fu2c18u29u3btzu3dAustraliau2fSydney
# off=[(M-F,18),(S,13)]
off=u5bu28M-Fu2c18u29u2cu28Su2c13u29u5d

Public Holidays

In order to properly implement support for public holidays, make sure to include either skip-days or skip-days-from with your policy. This list should contain all of the public holidays you wish to address and must use YYYY-MM-DD syntax for its dates. If the date the policy is being run on matches any one of those dates, the policy will not return any resources. These dates include year as many holidays vary from year to year so year is required to prevent errors. A sample policy that would not start stopped instances on a public holiday might look like:

policies:
    - 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