Update existing security list ingress rules in OCI with the python SDK
Published: 2022-08-19 22:31:15

---
title: Update existing security list ingress rules in OCI with the python SDK
published: true
description:
tags: 
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kkz5eblwt66mlr4w7ujj.jpeg
# Use a ratio of 100:42 for best results.
---

### Prerequisites

- Some knowledge about python programming language
- OCI SDK for python. please check [here](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/pythonsdk.htm#SDK_for_Python) to install it, if you do not have it.

<aside>
💡 Feel free to follow along with from [this](http://github.com) GitHub repository
</aside>

## Introduction

Security lists are components of your VCN that are responsible for allowing traffic in and out of the VCN, they act like firewalls and are applied to the VNICs of your subnets or VCN. You specify the types of traffic allowed in and out with ingress and egress rules respectively.

As your VCN grows in complexity, there could be a need to update the security rules of your security list, this is fairly easy from the console but comes with a gotcha when using the API or SDK as stated in the [documentation](https://www.notion.so/Quotation-for-B2B-B2P-Logistics-Delivery-management-Application-4f6a2788b87e48548cf67de9b185b1a6) that `egressSecurityRules`or `ingressSecurityRules` objects you provide replace the entire existing objects. This means you risk replacing the entire rules in an existing security list when you are making an update to an existing security list.

In this article, you would learn how to use the python SDK to update the rules of an existing security list in OCI without losing the existing rules of course.


### Import oracle SDK

Let’s get started by preparing our environment and ensuring we have all that’s required to follow along this article.

The oracle python SDK provides the tools you need to interact with the Oracle Cloud Infrastructure using python, so let’s import the SDK module on the command line.

Run the command below in your terminal to install the oracle SDK:

```python
pip3 install oci
```

Next, create the file to write the python script using the command below:

```bash
touch oci-ingress-sl-update.py
```

This would create a file named `[oci-ingress-sl-update.py](http://oci-ingress-sl-update.py)`, feel free to update the file name.

Next, open the file you created in your favourite code editor, and the code below to import the oci SDK package:

```bash
import oci
```

## Authentication

You need to grant access to your tenancy, i would be authenticating using the instance principal, you can use other authentication methods as well:

```bash
config = oci.config.from_file()
identity_client = oci.identity.IdentityClient(config)
core_client = oci.core.VirtualNetworkClient(config)
```

This gets the credentials from the identity file and store in config, `oci.config.from_file()` takes as arguments, one is for the config file location and the other tells it it to use the `default` config profile. passing empty arguments falls back to default values with the config file at `~/.oci/identity_file` and the profile would be `default`.

We then use the config to authenticate the `identity_client` as well as the `core_client` which we would be using in a minute.

Next, we define the constants:

```bash
network_compartment_name = "network_compartment"
vcn_cidr_range = "10.104.0.0/16"
vcn_subnet_cidr_range = "10.103.225.0/28"
```

- `network_compartment_name` : The compartment that holds your network resources
- `vcn_cidr_range`: The virtual network’s CIDR range
- `vcn_subnet_cidr_range`: The Subnet’s CIDR range

## Get compartment data

We would be making use of the compartment id later on. In order to get this, we filter through the list of all compartments and match the compartment that matches the network compartment declared earlier.

Add the following code to get your compartment  id:

```bash
list_compartments_response = identity_client.list_compartments(
    compartment_id=config['tenancy'],
    lifecycle_state="ACTIVE")

for i in range(len(list_compartments_response.data)):
   if list_compartments_response.data[i].name == network_compartment_name:
     network_compartment_id = list_compartments_response.data[i].id
     break
```

Now we have the compartment id `network_compartment_id`, the next step is to identify the VCN we would be working with within the compartment.

Add the following code to get the VCN data below your script:

```bash
list_vcns_response = core_client.list_vcns(
    compartment_id=network_compartment_id)

for vcn in range(len(list_vcns_response.data)):
    if list_vcns_response.data[vcn].cidr_block == vcn_cidr_range[0]:
        vcn_id = list_vcns_response.data[vcn].id
        vcn_name = list_vcns_response.data[vcn].display_name
```

Here, we get the VCN name and id by filtering through the list of VCNs with the CIDR range declared earlier. You can also filter using the VCN name just like we did for the compartment, but i would be doing this way.

Now we have the compartment id and the VCN id, we use those details to get the VCNs security list. You would also need to specify the name of the security list since it’s possible to have multiple security lists in a VCN.

Go ahead and update your script with the following code to get your security list details:

```bash
list_security_lists_response = core_client.list_security_lists(
    compartment_id=network_compartment_id,
    vcn_id=vcn_id,
    display_name=sl_name,
 )

vcn_sl_id = list_security_lists_response.data[0].id

get_security_list_response = core_client.get_security_list(
    security_list_id=vcn_sl_id)

# get the current security list data
current_vcn_sl=json.loads(str(get_security_list_response.data.ingress_security_rules))
```

We simply get the first security list that matches the display name we specified to list_security_lists. Using the id we get the ingress rules for the security list and store it as a json object in `current_vcn_sl`. The reason we’re getting the existing rules is so that we are able to include the existing rules along with the updates and not replace them.

<aside>
💡 Remember, the idea is to update the ingress security rules

</aside>

It would also be nice to keep track of what the security rules are before making the update, the last thing you want to do is mess up the entire control plane without being able to revert the changes.

The following code would write the security rules to a file named `vcn_ingress_list.json` file. Again, feel free to change the file name to whatever suits your use case. The file would be available on the same directory as your script file as soon as you run the script.

```bash
with open('vcn_ingress_list.json', "w") as f:
   json.dump(current_vcn_sl, f, ensure_ascii=False, indent=4)
```

## Create the security list rules

We have declared all the data we need and we’re ready to start effecting the updates.

The first thing you want to do is to declare the ingress security rules you want to update as a python object.  i only have two rules to update to the VCN’s ingress security rules, these would tcp and imp connections on the VCN from the subnet. 

Update your file with the following code, replacing the rules with yours. You can create another file to hold the rules if you have a lot more.

```bash
sl_update_rules=[{
        'description': 'lcm_scan subnet cidr',
        'source': vcn_subnet_cidr_range,
        'source_type': 'CIDR_BLOCK',
        'icmp_options': None,
				'tcp_options': None,
        'is_stateless': False,
        'protocol': '6',
        'udp_options': None
      },{
        'description': 'lcm_scan subnet cidr',
        'source': vcn_subnet_cidr_range,
        'source_type': 'CIDR_BLOCK',
        'icmp_options': None,
				'tcp_options': None,
        'is_stateless': False,
        'protocol': '1',
        'udp_options': None
      }
]

sl_update_rules = current_vcn_sl_rules + sl_update_rules
```

Notice how we concatenate the current security rules with the update, that way we include the existing rules with the rules to deploy.

We also write out the new security list rules in another file named `sl_update_rules.json`:

```bash
# write out the new security list data
with open('sl_update_rules.json', "w") as f:
   json.dump(sl_update_rules, f, ensure_ascii=False, indent=4)
```

The API to update the security list doesn’t expect a JSON object, let’s create a function to update the rules into something the API expects using IngressSecurityRule, this function would be called for every one of the rules.

Add the `makeIngressRules` function below to your file:

```bash
def makeIngressRules(t):
    oci.core.models.IngressSecurityRule(
        source=t['source'],
        protocol=t['protocol'],
        source_type=t['source_type'],
        is_stateless=False,
        description=t['description'])
```

## Update Security Rules

Finally, we’re ready to deploy the new rules live. Update your code to reflect the method to make the call to update the security list:

```python
print("Updating "+vcn_sl_id)
core_client.update_security_list(
    security_list_id=vcn_sl_id,
    update_security_list_details=oci.core.models.UpdateSecurityListDetails(
        display_name=sl_display_name,
        ingress_security_rules=[makeIngressRules(t) for t in sl_update_rules]
))
```

Basically, this says; hey here’s my security list id, i would like to update it’s ingress security rules to now reflect the following rules. This would then convert the JSON security rules update the ingress security rules on the control plane.

Go ahead and run the scripts with the following command:

```bash
python3 oci-ingress-sl-update.py
```

Don’t forget to replace `oci-ingress-sl-update.py` with your filename including the file path. If everything goes well, the script should now update your ingress security rules and produce two JSON files, one containing the previous rules and the other one containing both the previous rules and the updates.

<aside>
💡 Remember, the script for this article is available [here](http://github.com)

</aside>

## Conclusion

Congratulations, you have learnt how to programatically update your ingress security rules without replacing the entire control plane. You can also update the egress rules using the same approach.

Thanks for reading, don’t forget to like and share this article. Follow me on twitter and everywhere else @robogeek95.