Assigning a rate-based rule to WebACL in WAF classic on AWS

Assigning a rate-based rule to WebACL in WAF classic on AWS

You can assign rules to your WebACL in your WAF classic but what you can also do are assign rate-based rules to it. You will use this when you need to apply rate-limiting at your WAF level.

And if you are trying to do it via Cloudformation like below:

  Type: "AWS::WAFRegional::WebACL"
      Type: BLOCK
    MetricName: "MyWebACL"
    Name: MyWebACL
      - Action:
          Type: ALLOW
        Priority: 1
        RuleId: !Ref RateBasedRule

  Type: "AWS::WAFRegional::RateBasedRule"
    Name: MyRateBasedRule
    MetricName: "MyRateBasedRule"
    RateKey: "IP"
    RateLimit: 2000
      - DataId: !Ref IPSet
        Negated: false
        Type: "IPMatch"

This is not going to work since rate-based rule creation is supported via Cloudformation but association is not. This is a known issue at AWS end.

You can either do the association via console or else use AWS cli for the same if it is part of an automation.

You will need to first fetch a change token which gets associated with the change you are making to the WebACL.

When you want to create, update, or delete AWS WAF objects, get a change token and include the change token in the create, update, or delete request. Change tokens ensure that your application doesn't submit conflicting requests to AWS WAF.

Each create, update, or delete request must use a unique change token. If your application submits a GetChangeToken request and then submits a second GetChangeToken request before submitting a create, update, or delete request, the second GetChangeToken request returns the same value as the first GetChangeToken request.

When you use a change token in a create, update, or delete request, the status of the change token changes to PENDING , which indicates that AWS WAF is propagating the change to all AWS WAF servers. Use GetChangeTokenStatus to determine the status of your change token.

$ change_token=$(aws waf-regional get-change-token --output text) # this line is needed so that the output stored in the variable isn't enclosed in quotes
$ aws waf-regional update-web-acl --web-acl-id ${web_acl_id} --change-token ${change_token} --updates Action="INSERT",ActivatedRule="{Priority=1,RuleId=${rule_id},Action={Type=\"BLOCK\"},Type=\"RATE_BASED\"}"