Part 2
In Part 1 I gave an overview of the Peanut Butter and Chocolate Project. In Part 2 I will cover the required PowerShell modules for the deployment, the settings used in the project, authenticating tp Azure and AWS, deploying the Azure Function App, and Deploying the AWS CodeCommit repository. I also demonstrate how to verify the resource deployments with Pester.
As a reminder, you can obtain the project code from https://github.com/markekraus/PeanutButterChocolate
Series Table of Contents
- Part 1 of 6: Project Introduction and Overview
- Part 2 of 6 (This Post): Project Settings, Authentication, Azure Function App Deployment, and AWS Code Commit Deployment
- Part 3 of 6: Creating AWS IAM User for Git, Generating HTTPS Git Credentials, Configuring Azure Web App External Git Deployment, and Initial Manual Deployment
- Part 4 of 6: Create AWS IAM Role, Deploy the C# .NET Core 2.0 AWS Lambda, and Create an AWS KMS Key
- Part 5 of 6: Add AWS CodeCommit Trigger and Encrypt Secrets with AWS KMS
- Part 6 of 6: Generate Configuration File, Automatic deployment from AWS CodeCommit to Azure Functions, Trigger the Azure Function from PowerShell, and Series Conclusion
Install and Import the Required Modules
The Configuration.ps1 starts off with installing and Importing the 3 modules used to deploy the pipeline: AzureRM, AWSPowerShell, and Pester. If you have the AzureRM and AWSPowerShell modules already installed, you may want to consider updating. I included the versions of the modules used at the time of authoring this project. Older versions may not work. Pester 4.2.0 was released 1 day before Part 1 of this series. I use features that were added in 4.2.0 in this project so you may very likely need to update Pester if you are following along with this series as it is being written.
Settings
Before we can begin adding resource, we need to define all the settings for the project. I use a $Settings HashTable for this. Using a settings HashTable makes it easier to find all the places in the script where the settings are used. It also makes intellisense easier to use in the project while developing it. Finally, this also make it easy to move the settings out to a psd1 file and then import it with Import-PowerShellDataFile without having to make significant changes to the logic in the code.
First thing we do is grab the AWS Access Key and Secret Key for the AWS admin user. The AWS cmdlets actually take these both as plain-text strings. Later in the settings HashTable I convert the Secret Key from a SecureString to a String. I'm not fond of secrets ever being in plain-text, so I often use this method to keep plain-text secrets safe when the cmdlet doesn't accept SecureStrings for secrets.
Next, we establish the base directory. You should run the Configuration.ps1 from the root directory of the project. I use this method because I often run scripts from VS Code with highlighting sections and pressing F8 to execute one chunk of code at a time. The $PSScriptRoot variable is not populated unless you are actually invoking a script. In which case, $PWD is used to establish the base directory in an console or editor session. The $BaseDir variable is used by several settings to determine locations for project source files.
I included comments for each of the settings explaining what they are. Rather list them off one-by-one here, I will just post the settings HashTable and you can refer to the comments within.
The AppName setting will need to be something different. That must be unique within Azure.
The ResrouceGroupLocation and AwsRegion settings need to support Azure Function Apps and AWS CodeCommit respectively.
Asset HashTables
I use 2 hashtables to store results from all the resource related commands. One HashTable is used for all Azure results and one HashTable is used for all AWS results. Several commands rely on information produced by the results of other commands. Those will also go in the asset HashTables. This is done to keep results grouped together and to assist with intellisense.
Authenticating to Azure and AWS
Next we get our our authentication configured. For Azure we actually authenticate and create a login session. For AWS, we are merely creating a credential profile and setting it as default. AWS cmdlets perform automatic authentication as needed, so this doesn't truly log you in or start an authentication session with AWS. If you messed up your AWS Access Key or Secret Key, you wont know until the first AWS commands are run.
I left Azure using the interactive login approach. This is a demo and since there is already one part that must be done interactively, I decided against including unattended login. I also did this out of fear of accidentally including my credentials in the demo. If you want to use certificate authentication or other means, you are welcome to update the code here before you run it.
Create the Azure Resource Group and Deploy an Azure Functions Web App
With all of the requirements out of the way, we can finally begin deploying resources. The first resource to deploy is the Azure Resource Group. This is a logical container that will contain the Azure Function Web App and its storage account. This will be deployed in the azure location specified in the settings. You must use a location where Azure Function Apps are supported.
With the resource group created, we can now deploy resources to the resource group. I wanted to try out template based deployment so I chose that method for this project. I am unsure if Azure Function Apps can be deployed without a template, as I haven't tried. I have deployed Web Apps with PowerShell cmdlets before, but never Function Apps. This deployment template is the base template provided by Microsoft https://github.com/Azure/azure-quickstart-templates/tree/master/101-function-app-create-dynamic. It will deploy a consumption plan Function App and its storage account. The storage account options are listed in the settings.
Now we use Pester to verify the deployment:
If all goes well you should see results like this:
In the azure portal the Resource Group should have an App Service Plan, and App Service and Storage Account
In the Function Apps the Function App should be visible.
There won't be any functions visible yet as we have not deployed any.
Get The Azure Function Web App Deployment Credentials
With the Function App deployed we can now obtain the deployment credentials.
The deployment credentials will later be included in a YAML file stored in the AWS CodeCommit repository with the password encrypted by AWS KMS. These credentials are used to trigger an external git deployment by posting a JSON submission to the Deployment Trigger URL.
KuduAuth is a basic authorization HTTP request header that will be used later to obtain the the master key and function key. These keys are used to allow the Azure Function to be triggered via HTTP. Kudu is engine that Azure Web Apps use for git deployments. It also controls the keys used for HTTP triggers. It you are trying to figure out automation for Web Apps and Functions, you will want to familiarize yourself with Kudu's API.
Deploy the AWS CodeCommit Repository
The AWS CodeCommit repository is where all the code for the Azure Functions will live for this particular Function App. If deploying multiple function apps, You will need to deploy one repository per Function App. The file and folder structure of that repository is rigid if you use the manual deployment method (which is what I use in this project). I will go in more detail about that structure later, but the key here is that using this POC requires one AWS CodeCommit repository per Azure Function App. You would need to devise a more custom deployment to house multiple Azure Functions Apps in a single CodeCommit.
The creation of the CodeCommit repository is very simple. It just requires a name and a description. It will be deployed in the AWS region set in the settings or the current region configured for your defaults This will be true of all AWS resources deployed. CodeCommit is the most restrictive as to its available regions. So make sure you select a region in the settings that can support CodeCommit.
Now we validate the CodeCommit deployment with Pester.
If it is successful you should see this:
It should also be visible in the AWS Management Console:
Part 2 End
I'm trying not to make monolithic posts and to break this series up into smaller parts that get published quickly. In Part 3 we will continue with creating more resources. I'm going to try and publish each part less than a week apart. This may be interrupted by the MVP Summit the first week of March.