Skip to content

Draft: Remove Azure pipeline task. Support protected files and remove need for rg permissions for service principal #39

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
36 changes: 0 additions & 36 deletions .github/workflows/azure-pipeline-build.yml

This file was deleted.

208 changes: 188 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,200 @@
# NGINXaaS for Azure Configuration Automation
# NGINXaaS for Azure Deployment Action

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a move in the right direction to come inline with Github Actions documentation 👍

  • Can you please file work to track Azure Pipelines separately? We want to move it to separate repo and follow Azure guidelines around Pipelines tasks.
  • I'd also suggest looking into usage for this Pipeline task. Are there any customers using this? If so, removing it completely is not a good idea. You may want to follow deprecation guidelines to point users to where the task is actually hosted from here on.

This repository hosts two essential projects that facilitate the management and deployment of NGINXaaS for Azure configurations. Both projects aim to automate the process of synchronizing NGINX configuration files, but they target different platforms and have unique features and notation. To learn more about NGINXaaS for Azure, please review the [product homepage](https://www.nginx.com/products/nginx/nginxaas-for-azure/).
This action supports managing the configuration of an [NGINXaaS for Azure](https://docs.nginx.com/nginxaas/azure/quickstart/overview/) deployment in a GitHub repository. It enables continuous deployment through GitHub workflows to automatically update the NGINXaaS for Azure deployment when changes are made to the NGINX configuration files stored in the repository. Additionally, one can update NGINX certificates that are already present in Azure key vault.

## Projects
## Connecting to Azure

### 1. Azure Pipeline Task
This action leverages the [Azure Login](https://github.com/marketplace/actions/azure-login) action for authenticating with Azure and performing update to an NGINXaaS for Azure deployment. Two different ways of authentication are supported:
- [Service principal with secrets](https://docs.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Cwindows#use-the-azure-login-action-with-a-service-principal-secret)
- [OpenID Connect](https://docs.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Cwindows#use-the-azure-login-action-with-openid-connect) (OIDC) with an Azure service principal using a Federated Identity Credential

This project provides a custom Azure pipeline task that automates the synchronization of NGINXaaS configuration files for Azure deployments. It supports both GitHub Action pipelines and Azure DevOps pipeline tasks. [Read more](./azure-pipeline/README.md).
### Sample workflow that authenticates with Azure using an Azure service principal with a secret

### 2. GitHub Action Task
```yaml
# File: .github/workflows/nginxForAzureDeploy.yml

This GitHub Action enables continuous deployment through GitHub workflows to automatically update the NGINXaaS for Azure deployment when changes are made to the NGINX configuration files stored in the repository. It also supports updating NGINX certificates that are present in Azure key vault. [Read more](./github-action/README.md).
name: Sync the NGINX configuration from the GitHub repository to an NGINXaaS for Azure deployment
on:
push:
branches:
- main
paths:
- config/**

## Comparison
jobs:
Deploy-NGINX-Configuration:
runs-on: ubuntu-latest
steps:
- name: 'Checkout repository'
uses: actions/checkout@v2

| Feature/Aspect | Azure Pipeline Task | GitHub Action Task |
|------------------------------------|------------------------------------|-------------------------------------|
| **CI/CD Automation** | Yes | Yes |
| **Configuration File Host** | GitHub Repos or Azure Repos | GitHub |
| **Security** | Pipelines in secured agents | Azure Login Action |
| **Authentication Methods** | Service Connection | Service Principal with Secrets, OIDC|
| **Certificate Handling** | No | Yes (Azure key vault) |
| **CI/CD Platform** | Azure DevOps | GitHub |
- name: 'Run Azure Login using an Azure service principal with a secret'
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

## Getting Started
- name: 'Sync the NGINX configuration from the GitHub repository to the NGINXaaS for Azure deployment'
uses: nginxinc/nginx-for-azure-deploy-action/github-action@v0.4.0
with:
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
nginx-deployment-name: ${{ secrets.NGINX_DEPLOYMENT_NAME }}
nginx-config-directory-path: config/
nginx-root-config-file: nginx.conf
transformed-nginx-config-directory-path: /etc/nginx/
debug: false
```

To get started with either of these projects, please refer to the detailed README files linked above.
### Sample workflow that authenticates with Azure using OIDC

## License
```yaml
# File: .github/workflows/nginxForAzureDeploy.yml

These projects are licensed under the Apache-2.0 License - see the [LICENSE.md](LICENSE) file for details.
name: Sync the NGINX configuration from the GitHub repository to an NGINXaaS for Azure deployment
on:
push:
branches:
- main
paths:
- config/**

permissions:
id-token: write
contents: read

jobs:
Deploy-NGINX-Configuration:
runs-on: ubuntu-latest
steps:
- name: 'Checkout repository'
uses: actions/checkout@v2

- name: 'Run Azure Login using OIDC'
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: 'Sync the NGINX configuration from the GitHub repository to the NGINXaaS for Azure deployment'
uses: nginxinc/nginx-for-azure-deploy-action/github-action@v0.4.0
with:
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
nginx-deployment-name: ${{ secrets.NGINX_DEPLOYMENT_NAME }}
nginx-config-directory-path: config/
nginx-root-config-file: nginx.conf
transformed-nginx-config-directory-path: /etc/nginx/
debug: false
```

> **Note:**
The service principal being used for authenticating with Azure should have access to manage the NGINXaaS deployment. For simplicity, this guide assumes that the service principal has `Contributor` role to manage the deployment. Refer [prerequisites](https://docs.nginx.com/nginxaas/azure/getting-started/prerequisites/) for details.

## Handling NGINX configuration file paths

To facilitate the migration of the existing NGINX configuration, NGINXaaS for Azure supports multiple-files configuration with each file uniquely identified by a file path, just like how NGINX configuration files are created and used in a self-hosting machine. An NGINX configuration file can include another file using the [include directive](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/). The file path used in an `include` directive can either be an absolute path or a relative path to the [prefix path](https://www.nginx.com/resources/wiki/start/topics/tutorials/installoptions/).

The following example shows two NGINX configuration files inside the `/etc/nginx` directory on disk are copied and stored in a GitHub repository under its `config` directory.

| File path on disk | File path in the repository |
| ------------------------------------ | --------------------------------- |
| /etc/nginx/nginx.conf | /config/nginx.conf |
| /etc/nginx/sites-enabled/mysite.conf | /config/sites-enabled/mysite.conf |

To use this action to sync the configuration files from this example, the directory path relative to the GitHub repository root `config/` is set to the action's input `nginx-config-directory-path` for the action to find and package the configuration files. The root file `nginx.conf` is set to the input `nginx-root-config-file`.

```yaml
- name: 'Sync the NGINX configuration from the GitHub repository to the NGINXaaS for Azure deployment'
uses: nginxinc/nginx-for-azure-deploy-action/github-action@v0.4.0
with:
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
nginx-deployment-name: ${{ secrets.NGINX_DEPLOYMENT_NAME }}
nginx-config-directory-path: config/
nginx-root-config-file: nginx.conf
debug: false
```

By default, the action uses a file's relative path to `nginx-config-directory-path` in the repository as the file path in the NGINXaaS for Azure deployment.

| File path on disk | File path in the repository | File path in the NGINXaaS for Azure deployment |
| ------------------------------------ | --------------------------------- | ---------------------------------------------- |
| /etc/nginx/nginx.conf | /config/nginx.conf | nginx.conf |
| /etc/nginx/sites-enabled/mysite.conf | /config/sites-enabled/mysite.conf | sites-enabled/mysite.conf |

The default file path handling works for the case of using relative paths in `include` directives, for example, if the root `nginx.conf` references `mysite.conf` using:

```
include sites-enabled/mysite.conf;
```

For the case of using absolute paths in `include` directives, for example, if the root `nginx.conf` references `mysite.conf` using:

```
include /etc/nginx/sites-enabled/mysite.conf;
```

The action supports an optional input `transformed-nginx-config-directory-path` to transform the absolute path of the configuration directory in the NGINXaaS for Azure deployment. The absolute configuration directory path on disk `/etc/nginx/` can be set to `transformed-nginx-config-directory-path` as follows to ensure the configuration files using absolute paths in `include` directives work as expected in the NGINXaaS for Azure deployment.

```yaml
- name: 'Sync the NGINX configuration from the Git repository to the NGINXaaS for Azure deployment'
uses: nginxinc/nginx-for-azure-deploy-action/github-action@v0.4.0
with:
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
nginx-deployment-name: ${{ secrets.NGINX_DEPLOYMENT_NAME }}
nginx-config-directory-path: config/
nginx-root-config-file: nginx.conf
transformed-nginx-config-directory-path: /etc/nginx/
debug: false
```
The transformed paths of the two configuration files in the NGINXaaS for Azure deployment are summarized in the following table

| File path on disk | File path in the repository | File path in the NGINXaaS for Azure deployment |
| ------------------------------------ | --------------------------------- | ---------------------------------------------- |
| /etc/nginx/nginx.conf | /config/nginx.conf | /etc/nginx/nginx.conf |
| /etc/nginx/sites-enabled/mysite.conf | /config/sites-enabled/mysite.conf | /etc/nginx/sites-enabled/mysite.conf |

## Handling NGINX certificates

Since certificates are secrets, it is assumed they are stored in Azure key vault. One can provide multiple certificate entries to the github action as an array of JSON objects with keys:

`certificateName`- A unique name for the certificate entry

`keyvaultSecret`- The secret ID for the certificate on Azure key vault

`certificateVirtualPath`- This path must match one or more ssl_certificate directive file arguments in your Nginx configuration; and must be unique between certificates within the same deployment

`keyVirtualPath`- This path must match one or more ssl_certificate_key directive file arguments in your Nginx configuration; and must be unique between certificates within the same deployment

See the example below

```yaml
- name: "Sync NGINX certificates to NGINXaaS for Azure"
uses: nginxinc/nginx-for-azure-deploy-action/github-action@v0.4.0
with:
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
nginx-deployment-name: ${{ secrets.NGINX_DEPLOYMENT_NAME }}
nginx-deployment-location: ${{ secrets.NGINX_DEPLOYMENT_LOCATION }}
nginx-certificates: '[{"certificateName": "$NGINX_CERT_NAME", "keyvaultSecret": "https://$NGINX_VAULT_NAME.vault.azure.net/secrets/$NGINX_CERT_NAME", "certificateVirtualPath": "/etc/nginx/ssl/my-cert.crt", "keyVirtualPath": "/etc/nginx/ssl/my-cert.key" } ]'
debug: false
```

## Handling NGINX configuration and certificates

```yaml
- name: "Sync NGINX configuration- multi file and certificate to NGINXaaS for Azure"
uses: nginxinc/nginx-for-azure-deploy-action/github-action@v0.4.0
with:
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
resource-group-name: ${{ secrets.AZURE_RESOURCE_GROUP_NAME }}
nginx-deployment-name: ${{ secrets.NGINX_DEPLOYMENT_NAME }}
nginx-deployment-location: ${{ secrets.NGINX_DEPLOYMENT_LOCATION }}
nginx-config-directory-path: config/
nginx-root-config-file: nginx.conf
transformed-nginx-config-directory-path: /etc/nginx/
nginx-certificates: '[{"certificateName": "$NGINX_CERT_NAME", "keyvaultSecret": "https://$NGINX_VAULT_NAME.vault.azure.net/secrets/$NGINX_CERT_NAME", "certificateVirtualPath": "/etc/nginx/ssl/my-cert.crt", "keyVirtualPath": "/etc/nginx/ssl/my-cert.key" } ]'
debug: false
```
15 changes: 10 additions & 5 deletions github-action/action.yml → action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,19 @@ inputs:
default: "nginx.conf"
transformed-nginx-config-directory-path:
description: >
'The transformed absolute path of the NGINX configuration directory in NGINXaaS for Azure deployment, example: "/etc/nginx/".
If the "include" directive in the NGINX configuration files uses absolute paths, the path transformation
can be used to overwrite the file paths when the action synchronizes the files to the NGINXaaS for Azure deployment.'
'The absolute directory path in the NGINXaaS for Azure deployment where your configuration files will be placed.
All files found in the nginx-config-directory-path will be copied to this location in the deployment.
For example, use "/etc/nginx/" to match the standard NGINX directory structure on Azure.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, use "/etc/nginx/" to match the standard NGINX directory structure on Azure. -> For example, use "/etc/nginx/" to match the standard NGINX directory structure on your deployment. << something along these lines.

If your NGINX configuration files use absolute paths in "include" directives, this setting ensures those paths are correctly mapped in the deployment by prepending the specified directory.'
required: false
default: ""
nginx-certificates:
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
protected-files:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From an Actions perspective, this is a new feature in that it was not there earlier on and now we have added support for handling protected files via the action:

  • This should be done in a separate MR. You have the changes here which is fine but try splitting up the work so you are not refactoring the action and adding support for new (missing) things at the same time.
  • Separately, do we want to offer protected files support on git? Seems risky and something a customer may not want to use since they would not want to store sensitive stuff on git, right?

description: "Comma-separated list of file paths relative to nginx-config-directory-path that should be marked as protected. Example: 'ssl/private.key,conf.d/secrets.conf'"
required: false
default: ""
debug:
description: "Enable/Disable debug output."
required: false
Expand All @@ -40,10 +45,10 @@ runs:
using: "composite"
steps:
- name: "Synchronize NGINX certificate(s) from the Git repository to an NGINXaaS 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-certificates) }} --debug=${{ inputs.debug }}
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-certificates) }} --debug=${{ inputs.debug }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/kuthiala/nginx-for-azure-deploy-action/blob/f9dbec3c93f58bd3634762d4b2de1f2f0193a4d7/src/deploy-certificate.sh The input handling here needs to be fixed. I am okay if you want to preserve both but in that separate MR, I think you can safely consider refactoring configs and certs both as separate commits. Folks may have a preference in splitting that up further as the changeset will be a bit large but 👍

if: ${{ inputs.nginx-deployment-location != '' && inputs.nginx-certificates != '' }}
shell: bash
- name: "Synchronize NGINX configuration from the Git repository to an NGINXaaS for Azure deployment"
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 }} --debug=${{ inputs.debug }}
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 }} --nginx-config-directory-path=${{ inputs.nginx-config-directory-path }} --nginx-root-config-file=${{ inputs.nginx-root-config-file }} --transformed-nginx-config-directory-path=${{ inputs.transformed-nginx-config-directory-path }} --protected-files=${{ inputs.protected-files }} --debug=${{ inputs.debug }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's a quick suggestion:

I agree with what you are doing here but:

  • This MR is too big in scope as you are already removing the Azure Task.
  • And I see that we have only made changes to deploy-config.sh and not deploy-certificate.sh? 🤔

I'd recommend the following:

  • Keep this MR to retiring the Azure Pipeline Task.
  • Split up the rest of the work into its own where you are replacing what the Action itself is doing underneath:
    • You should also think about expanding the action use-cases in mind.
      • This repository currently has configs and certs. Do we want to preserve the flows as they stand with two separate scripts wrapped in a single action or do we want separate actions for managing certs vs configs.
      • Do we want to expand this action to create and update deployments?

if: ${{ inputs.nginx-config-directory-path != '' }}
shell: bash
4 changes: 0 additions & 4 deletions azure-pipeline/.gitignore

This file was deleted.

16 changes: 0 additions & 16 deletions azure-pipeline/example.yml

This file was deleted.

Binary file removed azure-pipeline/images/extension-icon.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-guidline-01.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-guidline-02.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-guidline-03.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-guidline-04.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-guidline-05.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-marketplace.png
Binary file not shown.
Binary file not shown.
Binary file removed azure-pipeline/images/readme-service-connections.png
Binary file not shown.
Binary file removed azure-pipeline/images/readme-token-scopes.png
Binary file not shown.
8 changes: 0 additions & 8 deletions azure-pipeline/jest.config.js

This file was deleted.

Loading
Loading