Jinja2 - References
On this page we will walk you through some of the references available within InsightCloudSec to use when configuring your Jinja2 templates.
The content on this page includes:
- Resource Attributes
- Resource Functions
- Using BotFactory Events with Jinja
- Example Jinja Templates
- Advanced templates for AWS bucket policies
For assistance with any of the examples or content on this page reach out to us through the Customer Support Portal.
Testing Jinja2 Code
You can test your Jinja code prior to running a Bot using the Preview message link located in the Actions section of the Bot Creation form.
Jinja2 Commands
Some Jinja2 commands may not work correctly until the Bot has deployed.
Resource Attributes
Available attributes vary based on the resource type (e.g. instances). A list of available attributes based on the resource type can be found through each category page, as follows:
- Compute Resources
- Storage Resources
- Network Resources
- Identity & Management Resources
- Container Resources
Finding a Specific Resource
We suggest navigating to the appropriate category page (e.g. Compute, Storage, etc.) and locating the individual resource. These are listed in the contents for each page on the right and can be accessed via that in-page Table of Contents, or by using a basic search on the page (e.g. CMD + F).
Using Resource Attributes
When using these actions, access resource properties by using the following syntax:
{{resource.<attribute>}}
Resource Common Data
For certain resources, the attribute details must be expressed in a slightly different format. Within InsightCloudSec there are a handful of resources that share what we refer to as common data and they are identified as such within our database.
To include these attributes you can access the properties of these specific resources with the following syntax:
{{resource.common.<attribute>}}
This syntax applies to ONLY the following:
text
1"resource_id",2"name",3"resource_type",4"organization_service_id",5"region_name",6"creation_timestamp",7"discovered_timestamp",8"modified_timestamp",9"namespace_id"
Example of common Jinja2 command
jinja2
1Resource type: {{resource.common.resource_type}}2Creation timestamp: {{resource.common.creation_timestamp}}34Note: Any formatting that applies to DATETIME fields can also be applied to resource common data date fields ("creation_timestamp", "discovered_timestamp", "modified_timestamp"), e.g., epoch format:5Creation Timestamp: {{resource.common.creation_timestamp.strftime('%s')}}678
Resource External Data
Accessing external data also requires a different format, as it directly references the external data parameters harvested by InsightCloudSec.
To include these external data parameters for a given resource ID, use the following syntax:
jinja2
1{{resource.get_resource_id()}}2{{resource.ext.<parameter>}}
The <parameter>
reference should be substituted with any of the named parameters found within a defined external data source. See Get Data Sources for more information.
**Example of external data Jinja2 command **
jinja2
1Cloud Account ID: {{resource.get_organization_service().account_id}}
Resource Functions
In addition to resource attributes InsightCloudSec includes support for some resource functions. Since our platform supports hundreds of resources if you are interested in a resource function or configuration that you do not see listed here reach out to our team through the Customer Support Portal.
When using these actions, you can access resource properties by using the following syntax:{{resource.<function>}}
Each of the resource functions below (listed alphabetically) provides a high-level explanation of the capability and the associated template element(s).
Create Network Flowlog
We have added Jinja2 field supports to the Bot action, Create Network Flow Log
. This capability allows you to dynamically assign S3, S3 folder, and/or Cloudwatch Logs based upon related properties (e.g. a badge of the resource’s cloud, the region of the resource, and/or the name of the resource.)
For example, this Jinja2 will create a flow log targeted at a standard S3 bucket for flowlogs by account and region and use a different folder defined by network ID.
jinja2
1arn:aws:s3:::aws-networkflowlogs-{{resource.get_organization_service().account_id}}-{{resource.common.region_name}}/{{resource.common.provider_id}}/
Get Access Key Info
You can include this resource function in a Bot configuration for the Cloud User Resource Type. Doing so will retrieve information about the API access keys including the key ID, key status, create date, last used date, and age in days for any users included within the Bot scope.
{{resource.get_access_key_info()}}
For example:
jinja2
1{2"access_key_id": "AKIA3ABCDEFGHIJLLMNOP",3"status": "active",4"create_date": "2019-10-29 20:31:40",5"last_used_date": "2019-11-20 22:05:00",6"age_in_days": 2667}
Get Age in Days
Allows you to retrieve information about the age of a resource in days and is applicable in any context where a date field is available. The create_date can be specified or will be assumed by default. Alternatively you can specify other dates fields, e.g. last_used_date, as a parameter.
Date fields are included in the attributes throughout our Resources documentation for each individual resource. For example, API Access Key details are here.
{{resource.get_age_in_days()}}
This template can also provide the number of days since a Cloud User's password has been used, as follows:
{{resource.get_age_in_days('password_last_used')}}
Get Attached Instance Name
The following {{resource.get_attached_instance_name()}}
allows you to pull the name of the attached compute(EC2) instance/NAT gateway on Public IP resources.
Get Badge Value by Key for Parent Cloud
This new function is specific to our Microsoft Teams Integration and enables users to include dynamic details based on a particular badge key. By defining a Badge for Teams, users are able to identify multiple channels to target for messaging using a single Bot action.Previously users would be required to create a single Bot action for each Teams channel using an individual webhook).
{{resource.get_badge_value_by_key_for_parent_cloud()}}
For example, where ‘Teams’ is your badge key:
{{resource.get_badge_value_by_key_for_parent_cloud('Teams')}}
In addition users can choose to specify case sensitivity and to return a default value with the following:
- Specify case sensitivity
case_insensitive
- Note that if not specified this value defaults to false
- Return a default value
default_return_str
For example, where case insensitivity is set to True and the default string is No Badge Found:{{resource.get_badge_value_by_key_for_parent_cloud('Teams', case_insensitive=True, default_return_str='No Badge Found')}}
.
Get Cloud Organization Details
The following "getters" can be used in Bot notification to enrich notifications:
resource.get_cloud_organization_id()
- Retrieves the cloud specific organization ID that's defined at the top level.resource.get_cloud_organization_nickname()
- Retrieves the human readable nickname that's associated with the Organization within InsightCloudSec.
Get Cloud Type
To return the cloud type (AWS, Azure, GCP, etc.), use the function below:
{{resource.get_cloud_type().id}}
Get Daily Cost
Calculate the daily cost for the resource in question. If the resource does not support cost calculation then this function will return None.
{{resource.get_daily_cost()}}
In addition, use the function below to round up and limit cost value to 2 decimal places.
For example:
- Cost with limiting 2 decimals: $2.23
- Cost without limiting decimals: $2.2272
{{"{0:.2F}". format(resource.get_daily_cost())}}
Get Data Collection Value
This template retrieves the description for a specific data collection value.
{{resource.get_data_collection_value(collection_name='<data_collection_name>', key='<data_collection_value>')}}
For example, the following template would return the description for the value mv_1
inside the my_dc
data collection: {{resource.get_data_collection_value('my_dc', key='mv_1')}}
Get Date, Timestamp, and Datetime
Calculate the date, timestamp, or datetime for a given event. These functions, in combination with a tagging strategy, can be used to provide context such as indicating when a resource was tagged with time-relevant keys, e.g. "Owner notified of impending delete", "30 day exemption granted", etc.
{{event.get_date()}}
{{event.get_date().today()}}
{{event.get_timestamp()}}
{{event.get_timestamp().utcnow()}}
{{event.get_unix_epoch_timestamp()}}
{{event.get_date(days=30)}}
{{event.get_timestamp(unit="minutes", value=60)}}
{{event.get_timestamp(unit="hours", value=12)}}
{{event.get_timestamp(unit="days", value=7)}}
In addition, the Filters Resource Tag Date Comparison
and Resource Tag Date/Time Comparison
, allow you to inspect those tags and make decisions based upon them, e.g. sending notifications, shutting down instances, deleting roles, etc.
Get Dependency IDs
Include the provider IDs of associated dependencies for a resource.
{{resource.get_dependency_ids()}}
Additionally, you can specify what type of resource as a dependency you want to list. For example, a bot scoped to Instances can have multiple dependencies (eg. Volumes, Networks, Subnets, etc). Use the syntax below to only list the Security Groups (or Access Lists).
{{resource.get_dependency_ids(resource_types=['resourceaccesslist'])}}
Get Impacted Resources
Include an optional tag key in the get_impacted_resources()
to enrich the response with the value of the supplied tag. This enhancement applies to the following resource types:
- AWS Trusted Advisor
- AWS GuardDuty
These fields can be used when a Bot is linked to an Insight. For example, a Bot flagging a resource can share the {{event.bot_insight_name}}
field to identify the specific Insight a resource is failing and to help the user more easily remedy the issue or add an exemption.
Get Last Event
This is a function that allows Bot authors to gain access to properties of the last eventof any type (from EDH) to further enrich Bot notification alerts. The syntax examples below allow you to obtain details from the last event object as follows:
- User -
{{resource.get_last_event().get('user')}}
- User ARN -
{{resource.get_last_event().get('user_arn')}}
- Action -
{{resource.get_last_event().get('action')}}
- Timestamp -
{{resource.get_last_event().get('timestamp')}}
- IP -
{{resource.get_last_event().get('ip')}}
- Event ID -
{{resource.get_last_event().get('event_id')}}
- Event Tags -
{{resource.get_last_event('tags')}}
- Event Created -
{{resource.get_last_event('create')}}
- Event Modify -
{{resource.get_last_event('modify')}}
To obtain the last suspicious event for a given resource, this function can be applied as follows: {{resource.get_last_event(None,True).get('user_arn')}}
.
Get Linked Insight
This function allows Bot authors to gain access to the Insight linked to the Bot.
{{event.insight_link}}
Get Missing Permissions
Use this option as part of Bot automation to help identify and remediate cloud accounts with missing IAM permissions that impair InsightCloudSec visibility. This can be used alongside the Query Filter Cloud Account With Impaired Visibility
.
{{resource.get_missing_permissions()}}
Get Monthly Cost
Calculate the monthly cost for the resource in question. If the resource does not support cost calculation then this function will return None.
{{resource.get_monthly_cost()}}
In addition, use the function below to round up and limit cost value to 2 decimal places.
For example:
- Cost with limiting 2 decimals: $2.23
- Cost without limiting decimals: $2.2272
{{"{0:.2F}". format(resource.get_monthly_cost())}}
Get Organization Service Name and Account ID
These walk the resource to the parent organization service (cloud account) to retrieve the name and account number assigned to the account (e.g. Acmecorp AWS Production and 123456789012).
{{resource.get_organization_service_name()}}
{{resource.get_organization_service().account_id}}
In addition, use the account_id
attribute in conjunction with the "Enable Storage Container Logging" Bot Action to enable logging to buckets in each region and account (provided they follow a standard naming convention):
ics-target-bucket-{{resource.common.region_name}}-{{resource.get_organization_service().account_id}}
Get Owner Name
In InsightCloudSec you can assign ownership to resources. Doing this grants the owner full permission to that resource, and designates a point of contact (POC) for questions about the resource. This function will return the name of the POC if one is assigned, and None if one is not.
{{resource.get_owner_name()}}
Another Example Using get_owner_name
{{resource.get_owner_name()}}@rapid7.com;{{resource.common.resource_type}}@rapid7.com
In this example a customer may have an alias for all S3 buckets. The buckets can be set up with a tag owner_email, and a Bot can be set up with condition on that tag key being present, and use the delayed email action with Jinja recipient, set to: {{resource.get_tag_value('owner_email', True, '')}}
Get Provider Link
Capture the provider link to create a notification (for Slack or other services) and share a direct link for the applicable resource in the provider console. (Currently only available for specific resources, contact us via Getting Support with any questions.)
{{resource.get_provider_link()}}.
An example of this notification type is:
Get Resource Age
This field {{resource.get_age_in_days()}}
allows you to retrieve the age of a resource. Including resource age information can provide meaningful context and allow users to generate notifications or take actions based upon a resource's age, e.g. rotating API keys once their age exceeds a user-defined threshold.
Get Resource CVEs
Provides a summary report of CVEs associated with the resource in question; currently valid for container images and container instances.
{{resource.get_resource_cves()}}
You can also limit CVEs to specific severities by including arguments:
{{resource.get_resource_cves(severities=['CRITICAL', 'HIGH'])}}
Get Resource Data
All
To return all the details about a resource, use the 'serialize' Jinja2 attribute shown below. Note that this can be used across all resource types, making it useful for bots that are scoped to more than one resource type.
{{resource.serialize(indent=2)}}
Example output:
jinja2
1{2"common": {3"resource_id": "instance...",4"resource_name": "Cloud_Account_Name",5"resource_type": "instance",6"cloud": "AWS",7"account": "Cloud_Account_Name",8"account_id": "...",9"account_status": "DEFAULT",10"organization_service_id": 1,11"availability_zone": "us-east-1a",12"region": "us-east-1",13"creation_timestamp": "2021-09-08 14:19:23",14"discovered_timestamp": "2021-09-07 13:30:47",15"modified_timestamp": "2021-09-16 16:16:50",16"namespace_id": "arn:aws:ec2:us-east-1:...",17"tags": {18"Name": "Cloud_Account_Name",19"Environment": "Development"20}21},22"instance_id": "i-...",23"instance_type": "t2.xlarge",24"launch_time": "2021-09-08T14:19:23Z",25"platform": "linux",26"state": "running",27"root_device_type": "ebs",28"key_name": "Key-Pair",29"image_id": "ami-...",30"private_ip_address": "123.123.123.123",31"public_ip_address": "123.123.123.123",32"tenancy": "default",33"network_resource_id": "privatenetwork...",34"subnet_resource_id": "privatesubnet...",35"detailed_monitoring": false,36"role_name": "InsightCloudSec-Power-User-Role",37"role_resource_id": "servicerole:...",38"aws_instance_metadata_service_v2_required": false,39"aws_instance_metadata_service_hop_limit": 1,40"aws_instance_metadata_service_endpoint_enabled": "enabled",41"aws_instance_metadata_service_endpoint_config_status": "applied",42"architecture": "x86_64",43"state_transition_reason": ""44}
Partial - Using a JMESPath Query
InsightCloudSec has added support for a JMESPath query to resource.serialize
, this allows you to:
- Access any field available on the serialized object
- Compose new JSON objects with the exact data and shape required
To use this feature you must pass a JMESPath expression as jmespath argument to resource.serialize
.
Some examples using this capability are below:
Get All Resource Tags
text
1{{resource.serialize(indent=2, jmespath="common.tags")}}23{4"Name": "Cloud_Account_Name",5"Environment": "Development"6}
Create a JSON Object with resource_id and tag values
text
1{{resource.serialize(indent=2, jmespath="{ResourceId: common.resource_id, TagValues: values(common.tags)}")}}23{4"ResourceId": "instance:1:us-east-1:i-0981d16c001ec0300:",5"TagValues": [6"Cloud_Account_Name",7"Development"8]9}
Create a JSON Object with account_id, instance_id, and environments from tags
text
1{{resource.serialize(indent=2, jmespath="{AccountId: common.account_id, InstanceId: instance_id, Environment: common.tags.Environment}")}}23{4"AccountId": "880056758000",5"InstanceId": "i-0981d16c001ec0300",6"Environment": "Development"7}
Get Resource Name
This walks the resource to the database object and returns the name. For resources which do not have a name, the primary key value is returned. With public IP addresses, for example, the resource’s IP address will be returned.
{{resource.get_resource_name()}}
This also works well with Bot actions that update S3 bucket policies, which require unique IDs, by using the bucket name, which is unique by definition. S3 bucket bot actions include object encryption and IP lockdown.
Get Tags from Cloud User via API Access Keys
You can include this resource function in a Bot configuration for the API Access Key Resource Type. Doing so will retrieve tag value(s) from the Cloud User using the API Access Key.
Input the tag key you're trying to retrieve the value for by replacing the key_here field, as shown in the example below:
{{resource.user.get_resource().get_tag_value(tag_key="key_here", case_insensitive=True)}}
Note
This function will only work with Users and is not applicable to any parent resource.
Get Tag Value
Get the value of a particular tag key. Only the tag key is required; however, you can optionally set the case_insensitive
and default_return_str
kwargs to force case sensitivity and/or return a specific value if the tag key does not exist.
{{resource.get_tag_value("tag_key", case_insensitive=True, default_return_str="None")}}
A tag key can be combined with the walk_parent_resource_group
parameter to return any resources tagged with the provided key, and when those resources do not have the provided tag key, check to see if the resource's Resource Group does. If the Resource Group does, that tag value will be returned instead. For example, with a key of "Owner":
{{resource.get_tag_value(tag_key="Owner", walk_parent_resource_group=True)}}
Get Threat Finding Details
Returns a list of threat finding JSON blocks for AWS GuardDuty findings matching the following response syntax:
{{resource.get_threat_finding_details()}}
To pretty-print the JSON output:
{{resource.get_threat_finding_details(json_format=true)}}
Get Users
Currently only applicable to Secure File Transfer.
Provides information pertaining to users authorized to SSH into target server, to include user_name
, public_keys
, key_id
, date_imported
, and home_directory_type
for each authorized user on the server.
{{resource.get_users()}}
Get Users Based on Credential Age
Identifies users whose server credentials are older than a given threshold, where n
is the number of days.
{{resource.get_users_based_on_credential_age(threshold=n)}}
When used in conjunction with the Transfer Server User Credential Threshold Filter, you can identify any users with expired credentials who are also associated with a given server.
Get Vulnerabilities
Enables the return of vulnerability findings for more robust tickets, Slack messages, and alerts. Input the following syntax to return all vulnerability findings for a given resource:
{{resource.get_vulnerabilities()}}
The example below loops over all the vulnerabilities on a resource to export information about the vulnerabilities:
1{% for vulnerability in resource.get_vulnerabilities() %}2{{ vulnerability.cve_id }} - {{ vulnerability.severity }} – {{ vulnerability.title }}3{% endfor %}
Using BotFactory Events with Jinja
To include Bot information on the Jinja output, use the following syntax:
text
1{{event.bot_<parameter>}}2{{event.<parameter>}}
Get Insight Information
Insight ID - {{event.bot_insight_id}}
Insight Name - {{event.bot_insight_name}}
Insight Severity - {{event.bot_insight_severity}}
These fields can be used when a Bot is linked to an Insight. For example, a Bot flagging a resource can share the {{event.bot_insight_name}}
field to identify the specific Insight a resource is failing and to help the user more easily remedy the issue or add an exemption.
Get Bot Information
Bot Name - {{event.bot_name}}
Bot ID - {{event.bot_id}}
Bot Link - {{event.direct_link}}
Bot Severity - {{event.bot_severity}}
Bot Description - {{event.bot_description}}
Bot Timestamp - {{event.timestamp}}
Example output:
Example Jinja Templates
Included below are several examples of dynamic messages that can be used in emails, Slack, and other messaging tools.
The title provides an explanation of their use case and includes the appropriate resource attributes and formatting. They can be copied and applied to any Bot you'd like to create.
To copy the message simply hover over the text to trigger the copy function and apply the pre-constructed template to your Bot.
Resource Is Exposed To Public
jinja2
1This `{{resource.get_organization_service().cloud_type_id}}` storage `{{resource.get_resource_name()}}` was made public, its located in `{{resource.region_name}}`23It belongs to:4Cloud account `{{resource. get_organization_service_name()}}`5Account ID `{{resource.get_organization_service().account_id}}`67Resource type `{{resource.common.resource_type}}`
Instance in Unapproved Region
jinja2
1An instance has been created in the unapproved region:`{{resource.common.region_name}}`2Instance Name: `{{resource.name}}`3Instance ID: `{{resource.instance_id}}`4Instance Launch Time: `{{resource.launch_time}}`56Instance Details:7{{resource.serialize(indent=2)}}
Ensure Tag Strategy is Enforced
jinja2
1A resource of type {{resource.get_resource_type()}} was discovered at2{{resource.common.creation_timestamp}} without the required *owner*3or *contact-email* tags. The resource name is `{{resource.get_resource_name()}}`.4It lives in account `{{resource.get_organization_service_name()}}`.
Instance Has More Than 4 Cores
jinja2
1`{{resource.name}}` has been created or discovered with more than 4 cores.2This resource will cost `${{resource.get_daily_cost()}}`/day.3The details are `{{resource.serialize(indent=2)}}`.4If this instance isn't downsized or cleaned up,5it will be deleted within 6 hours.
A Resource You Own Was Removed
jinja2
1The resource `{{resource.name}}` which belongs to you, has been deleted.2Details below: `{{resource.serialize(indent=2)}}`
Instance With Public IP Has SSH Open To The World
jinja2
1Instance `{{resource.instance_id}}` is `{{resource.state}}` and has a2public IP address of `{{resource.public_ip_address}}`. This instance has exposed3port 22 (SSH) open to the world. This instance is not within our security policy. Please4lock down the attached ACLs `{{resource.get_dependency_ids(resource_types=['resourceaccesslist'])}}`, or this instance will be5deleted in 4 hours.
Bad ACL
jinja2
1Bad ACL found on `{{resource.name}}`. Please login to investigate!
Expensive Instance was created or discovered
jinja2
1A very expensive instance `{{resource.get_resource_name()}}` created at2`{{resource.common.creation_timestamp}}` was found in account3`{{resource. get_organization_service_name()}}` which costs4`${{resource.get_daily_cost()}}/day` and `${{resource.get_monthly_cost()}}/mo`.
Database Open to the World
jinja2
1An insecure database was identified with access open to the World.2The details of this resource are:3`{{resource.serialize(indent=2)}}`.
Storage Container Public Access
jinja2
1An insecure storage container was identified with public permissions to the world.2The details of this resource are:3`{{resource.serialize(indent=2)}}`.4The resource has the following tags5`{{resource.serialize_tags(indent=2)}}`6This storage container is scheduled for deletion in 24 hours.7Please update security access rules to avoid the scheduled deletion.
CloudWatch Alarm has triggered
jinja2
1A CloudWatch Alarm has triggered. The data on the alarm is:2ID of the parent organization service (cloud): `{{resource.organization_service_id}}`3ID of alarm: `{{resource. alarm_id}}`4Name of Alarm: `{{resource.name}}`5ARN for the account where this alarm resides: `{{resource.common.provider_id}}`6An optional, brief description of this alarm: `{{resource.description}}`7Namespace (container for CloudWatch metrics) of the alarm: `{{resource.namespace}}`8Name of the metric this alarm checks for: `{{resource.metric_name}}`9User defined threshold for this alarm: `{{resource.threshold}}`10Amount of times this data will be evaluated before arriving at conclusion for alarm: `{{resource.evaluation_periods}}`11Alarm Type: `{{resource.state_value}}`12Alarm Reason: `{{resource.state_reason}}`13More data regarding this alarm: `{{resource.state_reason_data}}`
Database Instance has had Zero Connections in 14 days
jinja2
1Database instance `{{resource.name}}` has had no connections within 14 days. This database instance2resides in `{{resource.get_organization_service_name()}}` account and has an endpoint of3`{{resource.endpoint_address}}`.4This resource will have a snapshot taken, will be stopped, and finally deleted after 7 days.
Instance Provisioned outside of AMI Whitelist
jinja2
1'{{resource.image_id}}' has been used to provision instance `{{resource.instance_id}}`2in `{{resource.organization_service_name}}`. This machine image is not permitted.3This instance will have a snapshot taken, and be terminated immediately.
User without MFA Enabled
jinja2
1`{{resource.get_resource_type()}}: {{resource.get_resource_name()}}` in account `{{resource. get_organization_service_name()}}` with account # `{{resource.get_organization_service().account_id}}` does not have MFA enabled.
Advanced Jinja Templates (AWS)
In addition to templating for various notifications InsightCloudSec also supports the use of Jinja2 templating to add or update S3 bucket policies. These advanced capabilities are included here as examples/references of these capabilities. If you're interested in implementing Jinja2 in a more advanced way using custom policies we recommend connecting with our team through the Customer Support Portal.
In our two examples of updating bucket policy the first demonstrates the Jinja2 template required to enforce encryption, and the second is to restrict access.
Bucket Encryption Policy
If you would like to enforce encryption via bucket policy, you can create a bot that uses the Set Container Policy action and the following template to enforce encryption.
json
1{2"Version": "2012-10-17",3"Id": "bucketpolicyid:{{event.resource.get_resource_name()}}",4"Statement": [5{6"Sid": "DenyIncorrectEncryptionHeader",7"Effect": "Deny",8"Principal": "*",9"Action": "s3:PutObject",10"Resource": "arn:aws:s3:::{{event.resource.get_resource_name()}}/*",11"Condition": {12"StringNotEquals": {13"s3:x-amz-server-side-encryption": "AES256"14}15}16},17{18"Sid": "DenyUnEncryptedObjectUploads",19"Effect": "Deny",20"Principal": "*",21"Action": "s3:PutObject",22"Resource": "arn:aws:s3:::{{event.resource.get_resource_name()}}/*",23"Condition": {24"Null": {25"s3:x-amz-server-side-encryption": "true"26}27}28}29]30}
Bucket Lockdown Policy
If you would like to restrict bucket access to certain IP ranges or block specific IP ranges, you can use Set Container Policy and the following template to lock down the bucket to those IP ranges.
json
1{2"Version": "2012-10-17",3"Id": "bucketpolicyid:{{event.resource.get_resource_name()}}",4"Statement": [5{6"Sid": "IPAllow",7"Effect": "Allow",8"Principal": "*",9"Action": "s3:*",10"Resource": "arn:aws:s3:::{{event.resource.get_resource_name()}}/*",11"Condition": {12"NotIpAddress": {13"aws:SourceIp": "<insert IP range to block>"14},15"IpAddress": {16"aws:SourceIp": "<or insert IP range to allow>"17}18}19}20]21}