Skip to content

Certificate deployment in github action #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'NGINX configuration sync'
description: 'The action synchronizes NGINX configuration from a Git repository to an NGINX for Azure deployment.'
name: 'NGINX For Azure Deployment Sync'
description: 'The action synchronizes NGINX configuration from a Git repository and/or certificates already on Azure keyvault to an NGINX for Azure deployment'
inputs:
subscription-id:
description: 'The Azure subscription ID of the NGINX for Azure deployment.'
Expand All @@ -10,9 +10,12 @@ inputs:
nginx-deployment-name:
description: 'The name of the NGINX for Azure deployment.'
required: true
nginx-deployment-location:
description: 'The location where the NGINX deployment is located. Example westcentralus'
required: false
nginx-config-directory-path:
description: 'The NGINX configuration directory path relative to the root of the Git repository, example: "config/".'
required: true
required: false
nginx-root-config-file:
description: >
'The root NGINX configuration file path relative to the NGINX configuration directory in the Git repository, example: "nginx.conf".'
Expand All @@ -25,9 +28,17 @@ inputs:
can be used to overwrite the file paths when the action synchronizes the files to the NGINX for Azure deployment.'
required: false
default: ''
nginx-certificate-details:
description: 'An array of JSON objects each with keys nginx_cert_name, keyvault_secret, certificate_virtual_path and key_virtual_path. Example: [{"certificateName": "server1", "keyvaultSecret": "https://...", "certificateVirtualPath": "/etc/ssl/certs/server1.crt", "keyVirtualPath": "/etc/ssl/certs/server1.key" }, {"name": "server2", "keyvaultSecret": "https://...", "certificateVirtualPath": "/etc/ssl/certs/server2.crt", "keyVirtualPath": "/etc/ssl/certs/server2.key" }] '
required: false
runs:
using: "composite"
steps:
- name: 'Synchronize NGINX configuration from the Git repository to an NGINX for Azure deployment'
run: ${{github.action_path}}/src/deploy-config.sh ${{ inputs.subscription-id }} ${{ inputs.resource-group-name }} ${{ inputs.nginx-deployment-name }} ${{ inputs.nginx-config-directory-path }} ${{ inputs.nginx-root-config-file }} ${{ inputs.transformed-nginx-config-directory-path }}
run: ${{github.action_path}}/src/deploy-config.sh --subscription_id=${{ inputs.subscription-id }} --resource_group_name=${{ inputs.resource-group-name }} --nginx_deployment_name=${{ inputs.nginx-deployment-name }} --config_dir_path=${{ inputs.nginx-config-directory-path }} --root_config_file=${{ inputs.nginx-root-config-file }} --transformed_config_dir_path=${{ inputs.transformed-nginx-config-directory-path }}
if: ${{ inputs.nginx-config-directory-path != '' }}
shell: bash
- name: 'Synchronize NGINX certificate(s) from the Git repository to an NGINX for Azure deployment'
run: ${{github.action_path}}/src/deploy-certificate.sh --subscription_id=${{ inputs.subscription-id }} --resource_group_name=${{ inputs.resource-group-name }} --nginx_deployment_name=${{ inputs.nginx-deployment-name }} --nginx_resource_location=${{ inputs.nginx-deployment-location }} --certificates=${{ toJSON(inputs.nginx-certificate-details) }}
if: ${{ inputs.nginx-deployment-location != '' && inputs.nginx-certificate-details != '' }}
shell: bash
130 changes: 130 additions & 0 deletions src/deploy-certificate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

for i in "$@"
do
case $i in
--subscription_id=*)
subscription_id="${i#*=}"
shift
;;
--resource_group_name=*)
resource_group_name="${i#*=}"
shift
;;
--nginx_deployment_name=*)
nginx_deployment_name="${i#*=}"
shift
;;
--nginx_resource_location=*)
nginx_resource_location="${i#*=}"
shift
;;
--certificates=*)
certificates="${i#*=}"
shift
;;
*)
echo "Not matched option '${i#*=}' passed in."
exit 1
;;
esac
done

if [[ ! -v subscription_id ]];
then
echo "Please set 'subscription-id' ..."
exit 1
fi
if [[ ! -v resource_group_name ]];
then
echo "Please set 'resource-group-name' ..."
exit 1
fi
if [[ ! -v nginx_deployment_name ]];
then
echo "Please set 'nginx-deployment-name' ..."
exit 1
fi
if [[ ! -v nginx_resource_location ]];
then
echo "Please set 'nginx-resource-location' ..."
exit 1
fi
if [[ ! -v certificates ]];
then
echo "Please set 'nginx-certificate-details' ..."
exit 1
fi

arm_template_file="nginx-for-azure-certificate-template.json"

#get the ARM template file
wget -O "$arm_template_file" https://nginxgithubactions.blob.core.windows.net/armtemplates/nginx-for-azure-certificate-template.json
echo "Downloaded the ARM template for synchronizing NGINX certificate."

cat "$arm_template_file"
echo ""

az account set -s "$subscription_id" --verbose

count=$(echo $certificates | jq '. | length')
for (( i=0; i<count; i++ ));
do
nginx_cert_name=$(echo $certificates | jq -r '.['"$i"'].certificateName')
nginx_cert_file=$(echo $certificates | jq -r '.['"$i"'].certificateVirtualPath')
nginx_key_file=$(echo $certificates | jq -r '.['"$i"'].keyVirtualPath')
keyvault_secret=$(echo $certificates | jq -r '.['"$i"'].keyvaultSecret')

do_nginx_arm_deployment=1
err_msg=" "
if [ -z "$nginx_cert_name" ] || [ "$nginx_cert_name" = "null" ]
then
err_msg+="nginx_cert_name is empty;"
do_nginx_arm_deployment=0
fi
if [ -z "$nginx_cert_file" ] || [ "$nginx_cert_file" = "null" ]
then
err_msg+="nginx_cert_file is empty;"
do_nginx_arm_deployment=0
fi
if [ -z "$nginx_key_file" ] || [ "$nginx_key_file" = "null" ]
then
err_msg+="nginx_key_file is empty;"
do_nginx_arm_deployment=0
fi
if [ -z "$keyvault_secret" ] || [ "$keyvault_secret" = "null" ]
then
err_msg+="keyvault_secret is empty;"
do_nginx_arm_deployment=0
fi

uuid="$(cat /proc/sys/kernel/random/uuid)"
template_file="template-$uuid.json"
template_deployment_name="${nginx_deployment_name:0:20}-$uuid"

cp "$arm_template_file" "$template_file"

echo "Synchronizing NGINX certificate"
echo "Subscription ID: $subscription_id"
echo "Resource group name: $resource_group_name"
echo "NGINX for Azure deployment name: $nginx_deployment_name"
echo "NGINX for Azure Location: $nginx_resource_location"
echo "ARM template deployment name: $template_deployment_name"
echo ""
echo "NGINX for Azure cert name: $nginx_cert_name"
echo "NGINX for Azure cert file location: $nginx_cert_file"
echo "NGINX for Azure key file location: $nginx_key_file"
echo ""

if [ $do_nginx_arm_deployment -eq 1 ]
then
set +e
az deployment group create --name "$template_deployment_name" --resource-group "$resource_group_name" --template-file "$template_file" --parameters name="$nginx_cert_name" location="$nginx_resource_location" nginxDeploymentName="$nginx_deployment_name" certificateVirtualPath="$nginx_cert_file" keyVirtualPath="$nginx_key_file" keyVaultSecretID="$keyvault_secret" --verbose
set -e
else
echo "Skipping JSON object $i cert deployment with error:$err_msg"
echo ""
fi
done
66 changes: 60 additions & 6 deletions src/deploy-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,66 @@
set -euo pipefail
IFS=$'\n\t'

subscription_id=$1
resource_group_name=$2
nginx_deployment_name=$3
config_dir_path=$4
root_config_file=$5
transformed_config_dir_path=${6:-''}
transformed_config_dir_path=''
for i in "$@"
do
case $i in
--subscription_id=*)
subscription_id="${i#*=}"
shift
;;
--resource_group_name=*)
resource_group_name="${i#*=}"
shift
;;
--nginx_deployment_name=*)
nginx_deployment_name="${i#*=}"
shift
;;
--config_dir_path=*)
config_dir_path="${i#*=}"
shift
;;
--root_config_file=*)
root_config_file="${i#*=}"
shift
;;
--transformed_config_dir_path=*)
transformed_config_dir_path="${i#*=}"
shift
;;
*)
echo "Not matched option '${i#*=}' passed in."
exit 1
;;
esac
done

if [[ ! -v subscription_id ]];
then
echo "Please set 'subscription-id' ..."
exit 1
fi
if [[ ! -v resource_group_name ]];
then
echo "Please set 'resource-group-name' ..."
exit 1
fi
if [[ ! -v nginx_deployment_name ]];
then
echo "Please set 'nginx-deployment-name' ..."
exit 1
fi
if [[ ! -v config_dir_path ]];
then
echo "Please set 'nginx-config-directory-path' ..."
exit 1
fi
if [[ ! -v root_config_file ]];
then
echo "Please set 'nginx-root-config-file' ..."
exit 1
fi

# Validation and preprocessing

Expand Down
88 changes: 88 additions & 0 deletions src/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

for i in "$@"
do
case $i in
--subscription_id=*)
subscription_id="${i#*=}"
shift
;;
--resource_group_name=*)
resource_group_name="${i#*=}"
shift
;;
--nginx_deployment_name=*)
nginx_deployment_name="${i#*=}"
shift
;;
--nginx_resource_location=*)
nginx_resource_location="${i#*=}"
shift
;;
--config_dir_path=*)
config_dir_path="${i#*=}"
shift
;;
--root_config_file=*)
root_config_file="${i#*=}"
shift
;;
--transformed_config_dir_path=*)
transformed_config_dir_path="${i#*=}"
shift
;;
--certificates=*)
certificates="${i#*=}"
shift
;;
*)
echo "Not matched option '${i#*=}' passed in."
exit 1
;;
esac
done

if [[ ! -v subscription_id ]];
then
echo "Please set 'subscription-id' ..."
exit 1
fi
if [[ ! -v resource_group_name ]];
then
echo "Please set 'resource-group-name' ..."
exit 1
fi
if [[ ! -v nginx_deployment_name ]];
then
echo "Please set 'nginx-deployment-name' ..."
exit 1
fi

if [[ -v nginx_resource_location ]] && [[ -v certificates ]];
then
./deploy-certificate.sh \
--subscription_id="$subscription_id" \
--resource_group_name="$resource_group_name" \
--nginx_deployment_name="$nginx_deployment_name" \
--nginx_resource_location="$nginx_resource_location" \
--certificates="$certificates"
fi

if [[ ! -v transformed_config_dir_path ]];
then
transformed_config_dir_path=''
fi

if [[ -v config_dir_path ]] && [[ -v root_config_file ]];
then
./deploy-config.sh \
--subscription_id="$subscription_id" \
--resource_group_name="$resource_group_name" \
--nginx_deployment_name="$nginx_deployment_name" \
--config_dir_path="$config_dir_path" \
--root_config_file="$root_config_file" \
--transformed_config_dir_path="$transformed_config_dir_path"
fi

55 changes: 55 additions & 0 deletions src/nginx-for-azure-certificate-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"name": {
"type": "string",
"metadata": {
"description": "The name of the cert resource"
}
},
"location": {
"type": "string",
"metadata": {
"description": "The location for all resources"
}
},
"nginxDeploymentName": {
"type": "string",
"metadata": {
"description": "The name of your NGINX deployment resource"
}
},
"certificateVirtualPath": {
"type": "string",
"metadata": {
"description": "The file path of the certificate file"
}
},
"keyVirtualPath": {
"type": "string",
"metadata": {
"description": "The file path of the certificate key file"
}
},
"keyVaultSecretID": {
"type": "string",
"metadata": {
"description": "The secret ID of the key vault holding the certificate"
}
}
},
"resources": [
{
"type": "NGINX.NGINXPLUS/nginxDeployments/certificates",
"apiVersion": "2021-05-01-preview",
"name": "[concat(parameters('nginxDeploymentName'), concat('/', parameters('name')))]",
"location": "[parameters('location')]",
"properties": {
"certificateVirtualPath": "[parameters('certificateVirtualPath')]",
"keyVirtualPath": "[parameters('keyVirtualPath')]",
"keyVaultSecretId": "[parameters('keyVaultSecretID')]"
}
}
]
}