Posts
Accessing a Mulesoft API mock with curl
Using curl to access a Mulesoft API mock requires a little trick. Mulesoft gives you the ability to test out a mock of your API design. The easiest way to try the API is to click on the Documentation button on the right side of the API Designer, select an endpoint, and click “Try it.” If you have made the mock public, you can also use curl to test, but there is a little trick to using curl.
Google Apps Script: Spreadsheet to Document
For an explanation of this script, see Jeffrey Everhart’s excellent introduction to Apps Script.
function onOpen() {
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu('AutoFill Docs');
menu.addItem('Create New Docs', 'createNewGoogleDocs')
menu.addToUi();
}
function createNewGoogleDocs() {
//This value should be the id of your document template that we created in the last step
const googleDocTemplate = DriveApp.getFileById('1It9mTOqk0dVyPVaxmjRXa5tXdWMzgsaDxvb4Nm11nsM');
//This value should be the id of the folder where you want your completed documents stored
const destinationFolder = DriveApp.getFolderById('1jeg1V6q1ZJ6OWz-A4LNS5f8GtE9x4SQ4')
//Here we store the sheet as a variable
const sheet = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName('Data')
//Now we get all of the values as a 2D array
const rows = sheet.getDataRange().getValues();
//Start processing each spreadsheet row
rows.forEach(function(row, index){
//Here we check if this row is the headers, if so we skip it
if (index === 0) return;
//Here we check if a document has already been generated by looking at 'Document Link', if so we skip it
if (row[5]) return;
//Using the row data in a template literal, we make a copy of our template document in our destinationFolder
const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Employee Details` , destinationFolder)
//Once we have the copy, we then open it using the DocumentApp
const doc = DocumentApp.openById(copy.getId())
//All of the content lives in the body, so we get that for editing
const body = doc.getBody();
//In this line we do some friendly date formatting, that may or may not work for you locale
const friendlyDate = new Date(row[3]).toLocaleDateString();
//In these lines, we replace our replacement tokens with values from our spreadsheet row
body.replaceText('{{First Name}}', row[0]);
body.replaceText('{{Last Name}}', row[1]);
body.replaceText('{{Hours}}', row[2]);
body.replaceText('{{Date Completed}}', friendlyDate);
//We make our changes permanent by saving and closing the document
doc.saveAndClose();
//Store the url of our new document in a variable
const url = doc.getUrl();
//Write that value back to the 'Document Link' column in the spreadsheet.
sheet.getRange(index + 1, 6).setValue(url)
})
}Google Cloud Build for Cloud Functions
This post aims to add some missing information to Google’s docs about setting up CI/CD for Cloud Functions with Cloud Build.
Global vs Regional
Cloud Build triggers are globalby default. You can create a regional trigger in the Cloud Console by changing the location when editing or creating a trigger.NOTE: I can’t find any way at all to create a regional trigger with Terraform.
However, functions must be regional. The Google docs indicate that you must specify a region in your cloud build config file. If you’re using a global trigger, the `$LOCATION` substitution variable is set to global, and you’ll get a permission error when trying to deploy to a regional function. There are two options that I know of, and neither is great:
Terraform: for_each on a list of resources
Terraform provides a very simply way to use for_each to iterate over a list of resources. If you have a list of strings, use the toset() function to convert the list to a set of strings.
Example: assign a unique role on each resource
My use case is setting up a number of dev environments in Google Cloud Platform. The number may change as the size of the dev team increases, so I don’t want to hard-code the number of resources anywhere in my Terraform code. The number of environments is stored in the num_envs variable. For this example, I want to create a group of resources (Google Cloud Storage buckets). Each environment has its own service account, and I want each environment’s service account to have a specific role on that environment’s bucket. I also want to leverage official Google-supported Terraform modules whenever possible.
Using SSL Certificates with the Apache Tomcat Web Server
Creating PKCS12 Files
PKCS #12 is a format for storing multiple cryptography objects in a single archive file. You can store arbitrarily complex objects within a PKCS #12 archive, but the most common use is to store a single private key and its certificate chain. Create a PKCS12 file from PEM files:
openssl pkcs12 -export -in ssl_cert.pem -inkey key.pem -certfile bundle.crt -name "*.example.com" -out example.com.p12Depending on the product you’re working with, the documentation may call for a .pfx file instead of a .p12 file. PFX is an older format that was a predecessor to PKCS #12. In most modern systems, A PFX FILE AND A P12 FILE ARE EXACTLY THE SAME THING! You can just change the extension if needed and that will generally work. For example, the docs for ESET Security Management Center call for a pfx file, but a PKCS12 file will work just fine.
Auto-Create Multiple Blocks in a Terraform Resource
Learn how to automatically create multiple Terraform resources, and multiple blocks within one Terraform resource, using the for_each meta-argument and dynamic blocks.
Creating Multiple Resources
When using Terraform in a realistic environment (e.g. not a lab or tutorial), you often need to create automatically create multiple resources based on a list or map of data. This article reviews the options for creating resources based on data.There are two general methods to choose from when creating multiple resources:
The Best Mental Model for Writing Terraform Code
This article explains my current mental model of Terraform, in the hope that it will save you some time in your learning process. The foundation of using any programming language or software tool correctly is to develop a valid mental model for it, and refine your model as you learn more. There isn’t one correct mental model, and your mental model must evolve as your understanding grows.
Your introduction to writing Terraform code is usually through a very simple example. Unfortunately, simple examples can obscure some of the fundamental concepts of the language. For example, when I first started with Terraform, I did not understand the difference between a variable and a local. Variables need to be declared in a .tf file and defined (assigned a value) in a .tfstate file (or through other means). Variables seem complicated compared to locals. You can just assign a variable to a local and start using it, like a variable in Python. Why use variables when locals seem so much easier?
Define a Google Load Balancer and Cloud Storage bucket with Terraform
Here’s an example of using Terraform to define resources to host static content in a Google Cloud Storage bucket, fronted by a Cloud Load Balancer with a custom URL and SSL certificate. This example uses some other advanced features, such as Google Secrets and a map variable to define the SSL certificates. It’s pulled from a larger project, so this block of code isn’t guaranteed to run as-is. At a minimum, you’ll need to define the variables and set values.