Oracle Cloud Infrastructure (OCI) Functions is a serverless compute service that lets you create, run, and scale applications without managing any infrastructure. Functions are small but powerful blocks of code that generally do one simple thing. They are grouped into applications and stored as Docker images in a specified Docker registry. Functions can be invoked in response to a CLI command or signed HTTP request.
Here are some of the benefits of using OCI Functions:
Serverless: You don't have to provision or manage any infrastructure. OCI Functions takes care of all that for you.
Scalable: Functions can scale automatically to meet demand. You don't have to worry about provisioning enough capacity for your application.
Secure: OCI Functions is a secure service that is compliant with industry standards. Your code and data are protected.
Cost-effective: You only pay for the resources you use. There are no upfront costs or commitments.
I am going to showcase how to change VM shape when critical Memory alarm triggered using OCI functions.
Let's create function first :
Go to Developer services and Choose functions.
Let's create function :
Here i have set application name , shape and Network.
For Function deployment we can use either Cloud shell or Local.
Here i am using cloud shell
Login to Cloud Shell :
First we need to list Context and see you have right region context set :
fn list context
To set different region you can provide region name :
fn use context us-ashburn-1
Then we need to set Compartment where you have deployed this app
fn update context oracle.compartment-id ocid1.compartment
We need to create container registry to store Function container image . Here i am using Oracle Container registry
fn update context registry iad.ocir.io/tenancynamespace/prefix
To connect this container registry we need to Generate your Auth token
Login to OCI registry and Enter Auth token
docker login -u
Till here our context and Registry is ready , now we need to initialize function
Since i am going to use python script so i have initialized with runtime python.
fn init --runtime python compute
After initialize you will find three files : func.py,func.yaml & requirements.txt
Let's add our python script and renamed func.py to compute.py
In this example i am going to change VM shape with higher resources when function invoked by Memory alarm.
import io
import json
import oci
from fdk import response
def increase_compute_shape(instance_id, alarm_msg_shape):
signer = oci.auth.signers.get_resource_principals_signer()
compute_client = oci.core.ComputeClient(config={}, signer=signer)
current_shape = compute_client.get_instance(instance_id).data.shape
print("INFO: current shape for Instance {0}: {1}".format(instance_id,current_shape), flush=True)
if current_shape != alarm_msg_shape:
return "The shape of Instance {} differs from the Alarm message".format(instance_id)
# improve the logic below to handle more scenarios, make sure the shapes you select are available in the region and AD
if current_shape == "VM.Standard1.1":
new_shape = "VM.Standard2.1"
elif current_shape == "VM.Standard.E2.1":
new_shape = "VM.Standard.E2.2"
else:
return "Instance {0} cannot get a bigger shape than its current shape {1}".format(instance_id,current_shape)
print("INFO: new shape for Instance {0}: {1}".format(instance_id,new_shape), flush=True)
try:
update_instance_details = oci.core.models.UpdateInstanceDetails(shape=new_shape)
resp = compute_client.update_instance(instance_id=instance_id, update_instance_details=update_instance_details)
print(resp, flush=True)
except Exception as ex:
print('ERROR: cannot update instance {}'.format(instance_id), flush=True)
raise
return "The shape of Instance {} is updated, the instance is rebooting...".format(instance_id)
def handler(ctx, data: io.BytesIO=None):
alarm_msg = {}
message_id = func_response = ""
try:
headers = ctx.Headers()
message_id = headers["x-oci-ns-messageid"]
except Exception as ex:
print('ERROR: Missing Message ID in the header', ex, flush=True)
raise
print("INFO: Message ID = ", message_id, flush=True)
# the Message Id can be stored in a database and be used to check for duplicate messages
try:
alarm_msg = json.loads(data.getvalue())
print("INFO: Alarm message: ")
print(alarm_msg, flush=True)
except (Exception, ValueError) as ex:
print(str(ex), flush=True)
if alarm_msg["type"] == "OK_TO_FIRING":
if alarm_msg["alarmMetaData"][0]["dimensions"]:
alarm_metric_dimension = alarm_msg["alarmMetaData"][0]["dimensions"][0] #assuming the first dimension matches the instance to resize
print("INFO: Instance to resize: ", alarm_metric_dimension["resourceId"], flush=True)
func_response = increase_compute_shape(alarm_metric_dimension["resourceId"], alarm_metric_dimension["shape"])
print("INFO: ", func_response, flush=True)
else:
print('ERROR: There is no metric dimension in this alarm message', flush=True)
func_response = "There is no metric dimension in this alarm message"
else:
print('INFO: Nothing to do, alarm is not FIRING', flush=True)
func_response = "Nothing to do, alarm is not FIRING"
return response.Response(
ctx,
response_data=func_response,
headers={"Content-Type": "application/json"}
)
In this python script i am using OCI module so i have to update requirements with OCI.
Then i have updated func.yaml with my compute.py script name
Now all our function files ready ,let's deploy this function :
fn -v deploy --app computeapp
After Deployment in your computeapp you will find image and endpoint details.
To test this function i have deployed Test-linux VM with shape VM.standard.E2.1
To set alarm we need to create topic and subscription in Notifications.
I have created topic Name : Memory_alrm
Then i have created subscription where i have specified protocol Function and choose my compute function.
Now our subscription is ready.
Let's Create Alarm. In alarm i have choose Metric Namespace: oci_computeagent and Metric name : MemoryUtilization
In Metric Dimensions i have specified VM name: Test-linux
For Destination it will trigger Memory_alrm topic which will invoke function to change shape.
Let's generate Memory load using Stress-ng this will trigger this alarm which further invoke function to change this VM shape.
As you can see Alarm triggered as we have continuous 100% memory utlization for 1 min.
If you check function logs it is invoked and triggered VM shape change to VM.standard.E2.2
Now my instance going to stop to set this image shape change.
Finally my Instance shape change to VM.standard.E2.2
This is just one example , you can do lot more with OCI functions.
Comments