Connection au remote backend depuis GitHub
Les fichiers states permettent de déterminer les modifications à apporter à une infrastructure en comparant la configuration Terraform à l’existant. Le backend Azurerm permet de stocker les fichiers states dans un Azure storage, dont L'authentification peut être réalisée de différentes manières :
-
Azure CLI
-
Service Principal
-
Azure AD
-
OIDC
-
SAS Token
-
MSI (Managed security identity)
Shared Access Signature (SAS) Tokens
Les SAS tokens permettent de déléguer l’accès au storage account, au conteneur ou même à un blob, tout en permettant un contrôle poussé de l’accès (durée, filtrage d'IP…). Il impose par contre de gérer le renouvellement du jeton et ainsi que sa sécurité. Pour ce dernier point, Terraform recommande d’utiliser la configuration partielle du backend et de définir le SAS token dans les variables d’environnement: ARM_SAS_TOKEN
.
END_DATE=$(date -u -d "+2 years" +%Y-%m-%dT%H:%MZ) (1)
ARM_SAS_TOKEN=$(az storage container generate-sas -n $CONTAINER_NAME --account-key $ACCOUNT_KEY --account-name $TF_STORAGE_ACCOUNT --https-only --permissions dlrw --expiry $END_DATE -o tsv)
1 | Période de validité de 2 ans |
Dans le repo GitHub du projet, aller dans ARM_SAS_TOKEN
et ayant pour valeur, le token généré.
Créer ensuite un nouveau workflow GitHub :
name: 'Terraform'
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
environment: production
env:
ARM_SAS_TOKEN: ${{ secrets.ARM_SAS_TOKEN }}
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v3
# Install the needed version of Terraform CLI
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.2.1
- name: Terraform Init
run: terraform init
Après exécution du workflow, le state doit être présent dans le conteneur.
Service Principal
Un service principal est une identité utilisée par les applications pour accéder aux ressources Azure. Cet accès est limité par les rôles (RBAC), ce qui permet de contrôler l’accessibilité aux ressources. Lorsque l’on crée un service principal, on obtient les informations d’identification.
$ az ad sp create-for-rbac --name="SP_NAME" --role="Contributor" --scopes="/subscriptions/SUBSCRIPTION_ID"
{ "appId": "00000000-0000-0000-0000-000000000000", "displayName": "SP_NAME", "password": "0000-0000-0000-0000-000000000000", "tenant": "0000-0000-0000-0000-000000000000" }
Il est possible de renseigner ces identifiants de différentes manières dans Terraform, mais il est recommandé d’utiliser les variables d’environnement. Dans GitHub, ajouter les secrets suivants :
ARM_CLIENT_ID="00000000-0000-0000-0000-000000000000" ARM_CLIENT_SECRET="00000000-0000-0000-0000-000000000000" ARM_SUBSCRIPTION_ID="00000000-0000-0000-0000-000000000000" ARM_TENANT_ID="00000000-0000-0000-0000-000000000000"
Le workflow est ensuite modifié pour inclure ces valeurs :
name: 'Terraform'
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
environment: production
env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v3
# Install the needed version of Terraform CLI
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.2.1
- name: Terraform Init
run: terraform init
Azure AD
La configuration de l’authentification Azure AD est assez proche de celle utilisant le service principal, sauf qu’elle n’utilise pas les access keys mais l'AD pour se connecter au backend.
backend "azurerm" {
storage_account_name = "ststate18465"
container_name = "tfstate"
key = "terraform.tfstate"
use_azuread_auth = true (1)
}
1 | Impose l’authentification Azure AD pour accéder au blob storage account |
A la place de la propriété use_azuread_auth , il est aussi possible de définir la variable d’environnement ARM_USE_AZUREAD
|
L’utilisation de l’authentification Azure AD nécessite d’assigner le rôle Storage Blob Data Owner
au service principal dans le storage. Dans le cas contraire, on obtient l’erreur suivante :
StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationPermissionMismatch" Message="This request is not authorized to perform this operation using this permission.
az role assignment create \
--role "Storage Blob Data Owner" \
--assignee 00000000-0000-0000-0000-000000000000 \
--scope "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/$TF_STORAGE_ACCOUNT/blobServices/default/containers/$CONTAINER_NAME"
La commande suivante permet de lister les particularités du rôle.
az role definition list \
--name "Storage Blob Data Owner" \
--output json \
--query '[].{actions:permissions[0].actions, notActions:permissions[0].notActions}'
La propagation du rôle peut prendre plusieurs minutes avant d’être effective. Lors du développement, les utilisateurs doivent également posséder ce rôle pour se connecter au conteneur. C’est un bon moyen pour protéger l’accès, mais cela peut être fastidieux à configurer. Il reste possible d’utiliser la configuration partielle et un SAS token. |