X

The latest cloud infrastructure announcements, technical solutions, and enterprise cloud insights.

Automating IT Operations with Oracle Functions

Raghavendra Prasad
Solutions Architect, Product Management

Oracle Functions is a fully managed, multi-tenant, highly scalable, functions-as-a-service platform. It’s built on enterprise-grade Oracle Cloud Infrastructure components and powered by the open source Fn Project serverless platform. Along with Oracle Events, Oracle Functions can deliver powerful capabilities for infrastructure and application automation. Together, they enable services to act automatically based on state changes in infrastructure resources, a common use case for enterprise IT environments.

This post walks through an example of a function that verifies whether a compute instance is tagged correctly when it’s provisioned. If the instance isn’t tagged properly, the function acts to stop the instance. This practice is common in infrastructure automation; it allows resources to be audited for compliance with internal governance policies as they are created, rather than after.

This function is triggered by the Instance - Launch End event, which the Compute service generates at the completion of instance provisioning, based on whether the instance succeeds or fails.

This example uses Oracle Cloud Infrastructure Search to search for Compute resources with a tag key of costcenter and tag value of 1234.

Diagram that shows the process flow of compute provisioning triggering an event, which can trigger a function to stop the instance if it does not comply with security policies.

Prerequisites

  • Set up your tenancy for Functions development.

  • Set up the Fn CLI with Oracle Functions.

  • To use and retrieve information about other Oracle Cloud Infrastructure services, include the function in a dynamic group. The following example rule allows functions in a specific compartment to be included in a dynamic group:

    ALL {resource.type = 'fnfunc', resource.compartment.id = 'ocid1.compartment.oc1..exampleuniqueID'}

    For more information, see To create a dynamic group.

  • Create or update policies to grant dynamic group access to resources.

    After your dynamic group is created, create a policy that allows the dynamic group to use the instances in the compartment. Your policy should look something like this:

    Allow dynamic-group  to use instances in compartment 

    For example:

    Allow dynamic-group demo-func-dyn-group to use instances in compartment demo-func-compartment

    For more information, see Policy Syntax.

Create an Application

Use the Oracle Cloud Infrastructure Console to create an application in Oracle Functions.

  1. From the navigation menu, select Developer Services, and then select Functions.

    Screenshot that shows the navigation menu in the Console, with Developer Services and Functions selected.

  2. Click Create Application and then enter values in the New Application dialog box. If you have previously created VCNs, they are listed, and you can select the appropriate subnet.

    Screenshot that shows the New Application dialog box.

  3. Open a terminal and create the Python function:

    fn init --runtime python stop-untagged-instance
     
    cd stop-untagged-instance
  4. In the requirements.txt file, add the following entries:

    fdk
    oci

    When the Compute service emits the Instance - Launch End event, the JSON looks as follows:

    {
      "eventType" : "com.oraclecloud.computeapi.launchinstance.end",
      "cloudEventsVersion" : "0.1",
      "eventTypeVersion" : "2.0",
      "source" : "ComputeApi",
      "eventTime" : "2020-03-04T21:24:16.151Z",
      "contentType" : "application/json",
      "data" : {
        "compartmentId" : "ocid1.compartment.oc1..exampleuniqueID",
        "compartmentName" : "sandbox",
        "resourceName" : "instance-20200304-1322",
        "resourceId" : "ocid1.instance.oc1.iad.exampleuniqueID",
        "availabilityDomain" : "QGaa:US-ASHBURN-AD-1",
        "additionalDetails" : {
          "imageId" : "ocid1.image.oc1.iad.exampleuniqueID",
          "shape" : "VM.Standard2.1",
          "type" : "CustomerVmi"
        }
      },
      "eventID" : "08a71051-cb5c-490d-8e47-2354cfe503b5",
      "extensions" : {
        "compartmentId" : "ocid1.compartment.oc1..exampleuniqueID"
      }
    }

    The resourceId is the instance identifier (OCID).

Following are some snippets of code from the func.py file:

  • From the JSON body, get the instance ID:

    body = json.loads(data.getvalue())
    instanceId = body["data"]["resourceId"]
  • Use a signer to authenticate to Oracle Cloud Infrastructure services:

    signer = oci.auth.signers.get_resource_principals_signer()
  • Use Oracle Cloud Infrastructure Search to verify whether the Compute instance is properly tagged:

    search_client = oci.resource_search.ResourceSearchClient(config={}, signer=signer)
    key="costcenter"
    value="1234"
    structured_search = oci.resource_search.models.StructuredSearchDetails(
    query="query instance resources where ((freeformTags.key != '{}' && freeformTags.value != '{}') && (identifier='{}'))".format(key,value,instanceId),
    type='Structured',
    matching_context_type=oci.resource_search.models.SearchDetails.MATCHING_CONTEXT_TYPE_NONE)
    results = search_client.search_resources(structured_search)
  • If the search finds that the instance was not tagged properly, then stop the instance:

    compute_client = oci.core.ComputeClient(config={}, signer=signer)
    try:
      if compute_client.get_instance(instanceId).data.lifecycle_state in ('RUNNING'):
      try:
          resp = compute_client.instance_action(instanceId,'STOP')
      except oci.exceptions.ServiceError as :
         print('Action failed. {0}'.format(e), flush=True)
        raise
      else:
       print('The instance {0} was in the incorrect state to stop'.format(instanceId),flush=True)
  • Deploy the function:

    fn deploy --app control-instance-app

Create an Events Rule

  1. In the navigation menu of the Console, select Application Integration, and then select Events Service.

    Screenshot that shows the navigation menu in the Console, with Application Integration and Events Service selected.

  2. Click Create Rule and enter values in the Edit Rule dialog box.

    In this example, the service name is Compute, the event type is Instance - Launch End, and the action to take is to call the stop-untagged-instance function in the control-instance-app function application.

    Screenshot that shows the Edit Rule dialog box with the specified values entered.

Test the Function

Launch a Compute instance with no tags.

Screenshot that shows an instance details page indicating that no tags are associated with the instance. The instance is in the Provisioning stage.

After a few minutes, you should see that the instance has stopped for you to take further action.

Screenshot that shows an instance details page indicating that no tags are associated with the instance. The instance is in the Stopped stage.

Conclusion

This post shows an example of how to implement IT compliance rules by using Cloud Events and Functions in Oracle Cloud Infrastructure.

Resources

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha