Building a Chat Bot - Part 1: using GCP
- What is covered in this article?
- What is NOT covered in this article?
- What pre-requisites do I need?
- Using Anaplan APIs on GCP
- Secret Manager
- Create a Google Cloud Function
- Examining the code
- Best Practice: Information encryption
- In summary
What is covered in this article?
First of multi-part articles, this article presents how to build creative integration designs using serverless platform on Google Cloud Platform (GCP). You will learn how to deploy a GCP Cloud function that makes a request to Anaplan Authentication Service to generate a token. You will also learn a popular concept of “principle of least privilege” and Identity & Access Management (IAM) in GCP to control access to code deployed on GCP.
What is NOT covered in this article?
This article does not cover details on following topics:
- Anaplan Authentication API
- Python scripting
- GCP Cloud Computing concepts (VM, Containers, Serverless, etc…)
What pre-requisites do I need?
- Knowledge of Anaplan Platform & Model Building Concepts.
- Familiarity with Anaplan APIs and their functionality.
- Python, Webhook concepts.
- Familiarity with GCP Cloud Computing concepts.
- Curiosity and passion for learning.
The objective of the multi-part articles is to present how to use different GCP services to build a DialogFlow bot that lets end users interact with Anaplan platform. We will use GCP serverless infrastructure, known as, GCP Cloud function, to interact with Anaplan.
To refresh memory on topics that were already covered in other articles (ex: CA Certificates, Bulk API, Transactional API, etc…), we will provide direct links to them throughout these multi-series articles. Below is the list of topics we are planning to present over several articles:
- Part 1: Authenticate to Anaplan and generate a valid token every time we want to call an Anaplan API.
- Part 2: Execute Anaplan Actions
- Part 3: Call Anaplan Transactional API
- Part 4: Learn how to interact with a DialogFlow bot and a webhook
You should be familiar with Anaplan concepts such as authentication, Anaplan actions, and transactional APIs. If you are new to Anaplan API, this article will give you a high-level summary of functionality Anaplan APIs provide. Remember, we will be building integrations using infrastructure and services on GCP.
Using Anaplan APIs on GCP
GCP (Google Cloud Platform) is a powerful set of services that can be leveraged to make the Anaplan experience even more interactive.
Our project, in this series of short articles, is to build & deploy small and efficient recipes on GCP. In the final part of the series, we will bring all that we learned together to address an interesting and interactive use case.
For this purpose, we will use and create several GCP resources like “cloud function” (serverless methods mainly meant to invoke Anaplan’s APIs).
The code we will use will be based on Python with some code from previous articles. However, nothing prevents you from using other languages. The real advantage in using Python with Cloud Function is that you can have an editable view of the code they are based on.
There will be a lot of references to previous articles and blogs in that series. We strongly recommend you visit those pages as there might be a lot of details on specific topics.
The objective of this part is to build a Google Cloud Function that will always be able to provide a valid token for each of your future API calls. Your Cloud Function will look like this:
We must consider security when it comes to passwords or passphrases. Your cloud function will access Anaplan credentials stored securely in a secret manager on GCP. The cloud function will, then, make a request to Anaplan Authentication Service API to get a valid Anaplan Authentication Token.
Unlike the article on Anaplan CloudWorks API where we had to implement a layer containing the canonical version of the famous requests library (in step 3), we will be using the urllib3 library. Its use might be a bit more complex than requests’ but the greatest advantage is that you will not have to handle runtime dependencies, the code you will write or download will be immediately executable.
Let’s get started
First, we need to start at the beginning: How are we going to handle authentication? Like any secured transaction performed on the web, Anaplan APIs need to embed the identity of the requester to successfully trigger intended action. As you know, Anaplan, in its version 2.0, supports a token-based authentication. This means, you need to prove you are a rightfully defined Anaplan user and then you’ll receive a token that you can use for around 35 minutes.
We have 2 ways to get authenticated to Anaplan:
- Send a first call to Anaplan API server with the actual credentials (Basic Authentication).
- Use CA certificates.
We will show here the first method (if requested, we will issue another article on a way to use CA certificates with cloud function and Secret manager). We strongly recommend you read this blog. It will give you a deep insight into the functioning of CA Cert based authentication method.
Anaplan Operations Excellence Group (OEG) advise: Using CA Certificate-based authentication will save you from the effort of updating your password every x months (3 months usually).
Note: as you can deduce, the actions will be triggered under a unique identity (usually a technical user linked to a generic email). In future, we might deliver the possibility to take into account the user calling for that action.
Whether you are using basic authentication (username, password) or CA Certificate authentication, you don’t want to store sensitive information such as passwords & passphrases in your code. GCP provides the ability to store sensitive information in a Secret Manager. It is a good practice to use GCP Secret Manager. Using Secret Manager, you are also able to control access to secret value via GCP IAM roles & permissions. This will help us define access using “principle of least privilege”.
Once you select the type of Anaplan authentication method, you will store credential information in a secret that’s created in Secret Manager. In this article, we will be using Anaplan’s Basic Authentication. Therefore, we will create a secret that will store the value in Secret Manager in username:password format. Following steps will help you navigate through the steps.
- Search for Secret Manager in the search window and select it.
- If this is the first time you are using GCP Secret Manager, you may need to enable Secret Manager API.
- Click on + CREATE SECRET
- Create a secret labeled AnaplanBasicCreds with a secret value of your anaplan username and password in username:password format. Then, click CREATE SECRET.
Before we start using our secret value in our Google Cloud Function code (python), we need to define access to this secret using “principle of least privilege”.
In the next section, we will assign a role of Secret Manager Secret Accessor to a service account. Google Cloud Function is run under a GCP service account. If you do not have a service account in your project, follow steps below to create a service account. If you already have a service account, skip to the step on assigning roles.
You may create a custom service account or a service account that’s provisioned when you enable Cloud Build API. Cloud Build API need to be enabled to create and execute Cloud Functions.
Enable Cloud Build API
In this section, we will enable Cloud Build API. Once enabled, GCP will provision a service account under which Google Cloud Functions will run. Perform following steps to enable Cloud Build API.
- From GCP menu, select API & Services.
- Click + ENABLE APIS AND SERVICES
- Search for “cloud build api”
- Click on ENABLE to enable Cloud Build API
Once Cloud Build API is enabled, we want to ensure a service account has been created. You may choose to create a custom service account. However, for this article purpose, we will use this service account for Google Cloud Function execution.
- From GCP menu, select IAM & Admin.
- You should notice an App Engine default service account with Editor role.
Assign Secret Manager Secret Accessor role to Service Account.
We can now start building a Cloud Function. However, we need to assign this service account one additional role. We want this service account to be able to access secret value from the secret we created in Secret Manager. Secret Manager role “Secret Manager Secret Accessor” will allow Cloud Function to access a secret value. In the next section, we will assign the service account Secret Manager Secret Accessor role.
- Edit the service account.
- Under Edit Permissions window, click on + ADD ANOTHER ROLE
- Search for Secret Manager Secret Accessor role under “Select Role”
- Click SAVE.
Service Account, now, should have proper permissions to access secret value from Secret Manager in our Cloud Function.
Create a Google Cloud Function
In this section we will build a Google Cloud Function that does the following:
- Use secretmanager python package in google.cloud SDK library to access secret value for the secret, AnaplanBasicCreds, we created earlier.
- Using Anaplan credentials (username:password) from the secret manager, Cloud Function will make a request to Anaplan Authentication Service to generate Anaplan Authentication Token. This token will be used in subsequent Anaplan API calls for authentication.
- From GCP menu, select Cloud Functions.
- Click on + CREATE FUNCTION
- Provide a name and nearest region for the function (ex: AnaplanAuthToken) and click SAVE.
- Click Next
- Choose Python 3.9 for Runtime.
- Under main.py, delete any existing code.
- Now, it’s time to code a python script that will authenticate to Anaplan and generate authentication token.
- A python script is provided as an attachment with this article (cloud_function.py). Open this file in an editor and copy the code.
- Paste the code in the inline editor for main.py in Cloud Function.
- You will need to make slight modifications to this code. Update the code with your secret name (secret_name) and project_id. You can get name of project id on your home screen of GCP.
- In this python code, we are defining a function called getAnaplanAuthToken. Therefore, we must change the endpoint to use the same name as the function. Change the endpoint of this function from hello_world to getAnaplanAuthToken.
- We are using a set of libraries in this python code: urllib3, pybase64, and secretmanager. We want to ensure these libraries are installed on the system that’s running the Cloud Function. To ensure these libraries are installed, we will update the requirements.txt with dependent packages and their versions.
- Another file is provided with this article (requirements.txt). Copy and paste contents of this file in the inline editor for requirements.txt in Cloud Function.
- We will examine and explain the code in a later section.
- Click on DEPLOY to deploy your Cloud Function. Once your Cloud Function is successfully deployed, the dashboard will be updated with at green check mark.
- We can test our Cloud Function. Under Actions, select Test Function.
- Click TEST THE FUNCTION button. If there are no errors in the code, the function should return a token value.
Finally, how would we trigger this Cloud Function to run? Cloud Function could be triggered by a HTTPS request, Cloud Pub/Sub, or by an event on Cloud Storage. For example, you can have a Cloud Function triggered as soon as a file is added to Cloud Storage.
Examining the code
In this section, we will examine & explain the code.
First step in generating the authentication token is to retrieve secret value (username:password) from a secret in the Secret Manager. We are using Google’s Secret Manager Client Library for python to access secret values. You can access sample code at Google Cloud documentation here. One thing to note here. We are making a request to access secret value outside of the function at the beginning of the code. This ensures Secret Manager is accessed once and the value is available to rest of the code. This approach makes it much more efficient.
Once the secret value is accessed, it is used in a function to build a header with authentication information that’s encoded in base64. Essentially, the secret value (username:password) is base64 encoded. Authentication Service API request is made and the JSON response is parsed to return the tokenValue.
Best Practice: Information encryption
We managed to have our code working using basic authentication credential strings. Nevertheless, we may not want to have information stored in clear text. Even if we use a dedicated solution to store secrets, it would be more security-compliant if we can add another level of secrecy by encrypting.
In this previous article, we demonstrate some ways to encrypt. We recommend you follow these principles or use some of the tools that are available in that article to encrypt your information.
If there is enough interest and demand, we can consider providing step-by-step instructions on how to use those previous articles in the context of a lambda (don’t hesitate to request it in the comments section).
We now have a basis on which we can build upon for further interactions. For each Anaplan API call, it is required to have a valid token. Thanks to what we’ve seen in this article, you will be able to generate the token for each of your future API requests.
In the next article, we will see how to use this token to perform Anaplan’s API actions. Stay tuned and don’t hesitate to give your feedback in the comments section.
Got feedback on this content? Let us know in the comments below.
Contributing authors: Pavan Marpaka and Christophe Keomanivong.
I did all the steps and only left out the Authenticaltion credentials to be fake credentials. So, in the SECRET details for 'username:password', I have fake credentials. Did this factor alone "not" Deploy my function in GCP? I didn't want to hit client Anaplan cloud with the actual credentials. I have a learning Anaplan account for certificate-learning of modeling, and I wonder if this credential can be used to test apis/functions.
Otherwise, the whole material is top-notch. Already excited to try rest of the python apis.0
No. That wouldn't have caused a failure in deployment. Have you looked at the logs to see what's causing deployment failure? Could be somewhere in your Cloud Function python code. Sometimes, inconsistencies in tabs can cause this. Logs should give you specific reason as to which line in your code caused deployment failure.0
"getAnaplanCreds' in Cloud_function.py should be changed to "get AnaplanAuthToken".0