Using the python cdk, attempting to create a Web ACL with an IP whitelisting rule, but found that creating Web ACL rule properties does not work when trying to define an IP Set. I receive an error stating:
TypeError: Protocols cannot be instantiated
# Working rule prop, with aws managed rule group
rule_sql = wafv2.CfnWebACL.RuleProperty(
name='AWS-AWSManagedRulesSQLRuleSet',
statement=wafv2.CfnWebACL.StatementOneProperty(
managed_rule_group_statement=wafv2.CfnWebACL.ManagedRuleGroupStatementProperty(
vendor_name='AWS',
name='AWSManagedRulesSQLRuleSet'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AWS-AWSManagedRulesSQLRuleSet'
),
priority=0,
)
# Non-working rule prop, with IP set reference
rule_ip = wafv2.CfnWebACL.RuleProperty(
name='IPRule',
statement=wafv2.CfnWebACL.StatementOneProperty(
ip_set_reference_statement=wafv2.CfnWebACL.IPSetReferenceStatementProperty(
arn='myArn'
)
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='IPRule'
),
priority=0,
)
When synthing templates, this error is received:
File "...\infra\cdk.env\lib\site-packages\jsii_runtime.py", line 66, in __call__
inst = super().__call__(args, *kwargs)
File "...\infra\cdk\stacks\stacks_lib\static_site_hosting.py", line 56, in __init__
arn='myArn'
File "...\infra\cdk.env\lib\site-packages\typing_extensions.py", line 1545, in _no_init
raise TypeError('Protocols cannot be instantiated')
TypeError: Protocols cannot be instantiated
Linked somewhat to: https://github.com/aws/aws-cdk/issues/6056
This is :bug: Bug Report
As a workaround, I was able to implement the IPSetReferenceStatementProperty interface myself in python like so:
@jsii.implements(wafv2.CfnRuleGroup.IPSetReferenceStatementProperty)
class IPSetReferenceStatement:
@property
def arn(self):
return self._arn
@arn.setter
def arn(self, value):
self._arn = value
And then reference that new class instead:
ip_set_ref_stmnt = IPSetReferenceStatement()
ip_set_ref_stmnt.arn = whitelisted_ip_set.attr_arn
# Non-working rule prop, with IP set reference
whitelisted_ip_set_rule = wafv2.CfnWebACL.RuleProperty(
name='AllowedIPsRule',
statement=wafv2.CfnWebACL.StatementOneProperty(
ip_set_reference_statement=ip_set_ref_stmnt
),
visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='AllowedIPsRule'
),
priority=0,
)
At which point, I am able to CDK synth the template, and it captures the proper reference to the IP Set Reference Statement.
Ha!
Because of JSII naming conventions, IPSetReferenceStatementProperty will be interpreted as an interface, where it actually should be interpreted as a struct.
Our cfn2ts tool should have converted the name to IpSet (and probably WebACL => WebAcl).
In fact it should be an error if any of the L1 generators generate any class that JSII will interpret as an interface. It should be all classes and structs, no?
Here is the code from cdk8s that normalizes the IXXXFoo type names:
Since I'm still having issues with https://github.com/aws/aws-cdk/issues/6056, could this be related?
I am also facing this issue with error message TypeError: Protocols cannot be instantiated when using ipset_reference_statement=waf.CfnRuleGroup.IPSetReferenceStatementProperty(arn="arn:XXXXXXXXX".
IS there any ETA when this will be resolved.
As a workaround, I was able to implement the IPSetReferenceStatementProperty interface myself in python like so:
@jsii.implements(wafv2.CfnRuleGroup.IPSetReferenceStatementProperty) class IPSetReferenceStatement: @property def arn(self): return self._arn @arn.setter def arn(self, value): self._arn = valueAnd then reference that new class instead:
ip_set_ref_stmnt = IPSetReferenceStatement() ip_set_ref_stmnt.arn = whitelisted_ip_set.attr_arn # Non-working rule prop, with IP set reference whitelisted_ip_set_rule = wafv2.CfnWebACL.RuleProperty( name='AllowedIPsRule', statement=wafv2.CfnWebACL.StatementOneProperty( ip_set_reference_statement=ip_set_ref_stmnt ), visibility_config=wafv2.CfnWebACL.VisibilityConfigProperty( sampled_requests_enabled=True, cloud_watch_metrics_enabled=True, metric_name='AllowedIPsRule' ), priority=0, )At which point, I am able to CDK synth the template, and it captures the proper reference to the IP Set Reference Statement.
Thanks @KyleMuellerPFG - this enabled me to get an IP set working!
If anyone else finds this issue, note too that your IP rule can't contain the override_action parameter, or you'll get the error "Error reason: Your statement has multiple values set for a field that requires exactly one value., field: RULE," - because this is only valid for statements that refer to rule groups.
Most helpful comment
As a workaround, I was able to implement the IPSetReferenceStatementProperty interface myself in python like so:
And then reference that new class instead:
At which point, I am able to CDK synth the template, and it captures the proper reference to the IP Set Reference Statement.