November 15 2018

Provisioning Oracle API Platform Gateway Nodes using Terraform and Ansible on AWS

When using Oracle Autonomous API Platform, an API gets deployed to a logical gateway.  The logical gateway consists of one or more nodes which are instances of the runtime, installed on physical machines, virtual machines, or cloud infrastructure.  The gateway nodes handle the processing of the API requests, but a load balancer is still required to distribute traffic between the nodes.  When performance becomes an issue, more nodes can be added to increase throughput.  Providing an automated way to manage nodes ensures consistency of configurations and the ability to easily add and remove nodes.

 

The gateway nodes can be installed on-premise or in the cloud, and are not restricted to the Oracle cloud.  This allows for customers who are already using AWS to host their micro-services, to use Oracle's API Platform platform to be able to monitor and expose their APIs on a central location.  The API Platform portal, provides a central location deploy, activate, deprecate, and secure APIs while having complete visibility of the usages and KPI monitoring.

APICS Overview

In this blog, I'll describe how I've created an automated way to provision, configure, and register new API gateway nodes, running on Amazon EC2 into the API Platform using Terraform and Ansible.

 

Technologies used (and links for more help):

  • APICS: This the Oracle API Platform Cloud Service
  • AWS: Amazon Web Services - This will be used to host our EC2 instances and application load balancer
  • Terraform: A tool to write, plan, and create infrastructure as code. This is used to provision the network setup and create the AWS compute instances
  • Ansible: A tool to provide simple IT automation, including application deployment, configuration, and orchestration

Manual Provisioning, Configuring and Registering a new node

Likely the most time-consuming effort in adding new nodes to the gateway is in the provisioning of the server, whether it is virtual or physical.  The servers need to create, networking needs to be assigned, and a load balancer defined, pointing to each of the servers provisioned.  I'm not going to go into details on this (as it is automated later), but anyone that has had to do this, understands that it is very prone to user errors and can be a very tedious process.

 

Once the server has been provisioned, and the networking configured, software must be installed.  With any new server instance, software packages must be installed or updated, including the latest Java JDK.  Once base packages have been configured, the actual API Gateway installation files must be downloaded, unpacked, installed, configured to join the gateway.  

 

Although not overly complicated, the typical timeframe for all of this could be days or weeks for most organizations.  So why can't this be automated?  Well, of course, it can!

Automating it all

In this blog we will be using AWS EC2 instances, however, OCI could also be used because Terraform has providers for many cloud platforms.  Terraform is being used to provision the infrastructure and Ansible used to configure the software.   The provided script assumes that the logical gateway (DEV-Gateway) has already been created, and is waiting for nodes to join.   This step could be automated with the management API, however, in this example, the logical gateway already exists.

This code is available on Github.

Terraform

Using Terraform and the AWS API we will create the desired infrastructure, which includes 2 compute nodes, a load balancer, and the networking required, including private and public subnets, and security roles.

 

If you've never used Terraform before, see the getting started guide.  You can then take a look at the source code in Github to review the exact configuration and parameters that I've used.

AWS Network Diagram

Below is the description of the modules that Terraform created.

Terraform will perform the following actions:

  + module.compute.aws_instance.apics-node
  + module.compute.aws_key_pair.dev-key
  + module.compute.aws_security_group.apics-node
  + module.compute.aws_security_group_rule.apics-node-http
  + module.compute.aws_security_group_rule.apics-node-http-outbound
  + module.compute.aws_security_group_rule.apics-node-ssh
  + module.network.aws_eip.nat_eip
  + module.network.aws_internet_gateway.public-ig
  + module.network.aws_nat_gateway.nat_gw
  + module.network.aws_network_acl.private
  + module.network.aws_network_acl.public
  + module.network.aws_network_acl_rule.private-acl-egress-tcp
  + module.network.aws_network_acl_rule.private-acl-ingress-vpc
  + module.network.aws_network_acl_rule.public-acl-egress-tcp
  + module.network.aws_network_acl_rule.public-acl-ingress-tcp
  + module.network.aws_route.private-route-nat
  + module.network.aws_route.public-route-igw
  + module.network.aws_route_table.private-rtb
  + module.network.aws_route_table.public-rtb
  + module.network.aws_route_table_association.private-a
  + module.network.aws_route_table_association.private-b
  + module.network.aws_route_table_association.public-a
  + module.network.aws_route_table_association.public-b
  + module.network.aws_subnet.private-a
  + module.network.aws_subnet.private-b
  + module.network.aws_subnet.public-a
  + module.network.aws_subnet.public-b
  + module.network.aws_vpc.vpc


Plan: 28 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Ansible

Ansible provides 'playbooks' which define a set of instructions that install and configure software.  There are other configuration management tools, such as Puppet and Chef that can accomplish the same, but for this example, Ansible is being used.  Check out the Ansible quick start guide if you've never written a playbook, it provides an easy way to consistently and quickly ensure new systems have exactly the same setup.

 

Ansible playbooks are being invoked from Terraform after the creation of the compute instance.  These are used to configure the software running on the instance.

 

For the gateway node installation, a configuration JSON file is required that contains some installation properties (location, gateway name, gateway id, listen address, etc).  This is automatically built by Terraform (see screenshot) with the outputs from the network and node creation and transferred to the remote system just before executing the apicsgateway playbook.

  # build gateway-props.json file...
  provisioner "file" {
    content = <<EOD
{
   "nodeInstallDir"           : "/opt/oracle/gateway",
   "logicalGateway"           : "${var.logical-gateway}",
   "logicalGatewayId"         : "${var.logical-gateway-id}",
   "gatewayNodeName"          : "${var.gateway-name}-1",
   "managementServiceUrl"     : "${var.management-service-url}",
   "listenIpAddress"          : "${aws_instance.apics-node-1.private_ip}",
   "publishAddress"           : "${aws_lb.apics-lb.dns_name}",
   "gatewayExecutionMode"     : "${var.gateway-execution-mode}",
   "idcsUrl"                  : "${var.idcs-url}",
   "requestScope"             : "${var.request-scope}",
   "prevInstallCleanupAction" : "clean"
}
EOD
    destination = "/home/ec2-user/local-gateway-props.json"
    connection {
      type = "ssh"
      user = "ec2-user"
    }
  }

  # install apics gateway
  provisioner "local-exec" {
    command = "ansible-playbook -i configure/aws_hosts1 configure/playbook-install-configure-join-apicsgatewaynode.yml"
  }

}

During the install of the gateway node and the execution of the API Gateway install-configure-start-join command, there are several prompts for user input.  These prompts are handled by a module called 'pexpect'.  The module automatically reads the prompts and responds with the supplied values.


  - name: Call install-configure-start-join (takes a while ~8 min)
    become: false
    expect:
      command: "./APIGateway -f ../../local-gateway-props.json -a install-configure-start-join"
      chdir: "/opt/oracle/binaries/gateway/"
      timeout: 600
      responses:
        'Please enter user name for weblogic*' : "{{gateway_user}}"
        'Password*' :
          - "{{gateway_user_pass}}"
          - "{{gateway_manager_pass}}"
          - "{{gateway_manager_runtime_pass}}"
          - "{{gateway_manager_runtime_pass}}"
        'This action will now cleanup existing gateway*' : "y"
        'Please enter gateway manager user*' : "{{gateway_manager_user}}"
        'Please enter gateway manager client id*' : "{{client_id}}"
        'Please enter gateway manager client secret*' : "{{client_secret}}"
        'Please enter gateway manager runtime user*' : "{{gateway_manager_runtime_user}}"
        'Please enter gateway manager runtime client id*' : "{{client_id}}"
        'Please enter gateway manager runtime client secret*' : "{{client_secret}}"
        'Do you want to add the grant to gateway runtime user*' : "y"
        'Please enter gateway runtime user*' : "{{gateway_manager_runtime_user}}"
        'Would you like to create-join instead*' : "y"
      creates: "/opt/oracle/gateway/GATEWAY_HOME"

The first playbook (playbook-install-jdk8.yml) installs a newer version of Java, and the second playbook (playbook-install-configure-join-apicsgatewaynode.yml) executes the following tasks to set up the instance:

  • Initialize variable to validate if the gateway node has been previously installed (checks for the install directory)
  • Download the APIGateway archive
  • Create directory (to unpack archive into)
  • Unpack archive
  • Fix ownership of unpacked files
  • Cleanup archive
  • Install pexpect (will need to assist gateway installer)
  • Move configuration file (generated by terraform, and transferred earlier)
  • Call install-configure-start-join on APIGateway install
  • Retrieve the gateway node IDs using the management API
  • Update state to Active using the management API

Execution

The actual execution takes about 12 minutes.  Not a very exciting video, but this creates the entire infrastructure required for 2 nodes, with all of the software installed, and executes the registration of the new instance into the API Platform.

 

Below shows the 2 nodes registered and active.


DEV-Gateway

Using the service

I followed the Oracle tutorial Implementing APIs to build and deploy an API using APICS.

Deploy API

Below is the execution of the REST service from Postman.

Postman APICS Response

The APICS Reporting chart of requests.

Analytics

 

About the Author

Bio

Kevin King has over 11 years experience in enterprise scale implementations. Kevin is very experienced in architecting, modeling and developing solutions across many systems, internal and external.  These systems include ICS, DBCS, Weblogic domains, databases, EBS (cloud and on-prem), Java Web Services, SAP, and numerous Java APIs.

Join the Conversation

Enter your first name. It will only be used to display with your comment.
Enter your email. This will be used to validate you as a real user but will NOT be displayed with the comment.