Gestire le analogie tra ambienti usando flussi di lavoro riutilizzabili
Quando si distribuiscono le modifiche in più ambienti, i passaggi necessari per la distribuzione in ogni ambiente sono simili o addirittura identici. In questa unità si apprenderà come progettare i flussi di lavoro per evitare ripetizioni e consentire il riutilizzo del codice del flusso di lavoro.
Distribuzione in più ambienti
Dopo aver parlato con i colleghi del team del sito Web, si decide il flusso di lavoro seguente per il sito Web dell'azienda di giocattoli:
Il flusso di lavoro esegue il linter Bicep per verificare che il codice Bicep sia valido e segua le procedure consigliate.
Il linting avviene nel codice Bicep senza doversi connettere ad Azure, quindi non importa il numero di ambienti in cui si esegue la distribuzione. Viene eseguito una volta sola.
Il flusso di lavoro viene distribuito nell'ambiente di test e richiede:
- Esecuzione della convalida preliminare di Azure Resource Manager.
- Distribuzione del codice Bicep.
- Esecuzione di alcuni test sull'ambiente di test.
Se una parte del flusso di lavoro ha esito negativo, l'intero flusso di lavoro viene arrestato in modo da poter analizzare e risolvere il problema. Tuttavia, se tutto ha esito positivo, il flusso di lavoro continua a essere distribuito nell'ambiente di produzione:
- Il flusso di lavoro include un passaggio di anteprima, che esegue l'operazione di simulazione nell'ambiente di produzione per elencare le modifiche che verranno apportate alle risorse di Azure di produzione. L'operazione di simulazione convalida anche la distribuzione, quindi non è necessario eseguire un passaggio di convalida separato per l'ambiente di produzione.
- Il flusso di lavoro viene sospeso per la convalida manuale.
- Se viene ricevuta l'approvazione, il flusso di lavoro esegue i test di distribuzione e smoke test sull'ambiente di produzione.
Alcune di queste attività vengono ripetute tra gli ambienti di test e di produzione e alcune vengono eseguite solo per ambienti specifici:
Attività | Ambienti |
---|---|
Linting | Nessuno dei due: il linting non funziona su un ambiente |
Convalida | Solo test |
Anteprima | Solo produzione |
Distribuzione | Entrambi gli ambienti |
Smoke test | Entrambi gli ambienti |
Quando è necessario ripetere i passaggi nel flusso di lavoro, copiare e incollare le definizioni dei passaggi non è una procedura consigliata. È facile commettere accidentalmente piccoli errori o che si verifichino errori di sincronizzazione quando si duplica il codice del flusso di lavoro. E in futuro, quando sarà necessario apportare una modifica ai passaggi, si dovrà ricordare di applicare la modifica in più posizioni. Una procedura migliore consiste nell'usare flussi di lavoro riutilizzabili.
Flussi di lavoro riutilizzabili
GitHub Actions consente di creare sezioni riutilizzabili di definizioni del flusso di lavoro creando un file YAML del flusso di lavoro separato che definisce passaggi o processi. È possibile creare file YAML per riutilizzare più volte parti di un flusso di lavoro all'interno di un singolo flusso di lavoro o anche in più flussi di lavoro. Il flusso di lavoro riutilizzato è un flusso di lavoro chiamato e il flusso di lavoro che lo include è un flusso di lavoro chiamante. Concettualmente, si possono considerare simili ai moduli Bicep.
Quando si crea un flusso di lavoro riutilizzabile, si usa il trigger workflow_call
per indicare a GitHub Actions che il flusso di lavoro può essere chiamato da altri flussi di lavoro. Ecco un esempio di base di un flusso di lavoro riutilizzabile, salvato in un file denominato script.yml:
on:
workflow_call:
jobs:
say-hello:
runs-on: ubuntu-latest
steps:
- run: |
echo Hello world!
Nel flusso di lavoro chiamante si fa riferimento al flusso di lavoro chiamato includendo la parola chiave uses:
e specificando il percorso del flusso di lavoro chiamato all'interno del repository corrente:
on:
workflow_dispatch:
jobs:
job:
uses: ./.github/workflows/script.yml
È anche possibile fare riferimento a un file di definizione del flusso di lavoro in un altro repository.
Input e segreti del flusso di lavoro chiamato
È possibile usare input e segreti per semplificare il riutilizzo dei flussi di lavoro chiamati, perché è possibile consentire piccole differenze nei flussi di lavoro ogni volta che vengono usati.
Quando si crea un flusso di lavoro chiamato, è possibile indicare i relativi input e segreti all'inizio del file:
on:
workflow_call:
inputs:
environmentType:
required: true
type: string
secrets:
AZURE_CLIENT_ID:
required: true
AZURE_TENANT_ID:
required: true
AZURE_SUBSCRIPTION_ID:
required: true
È possibile definire tutti gli input e i segreti necessari. Ma proprio come i parametri Bicep, è meglio non usare gli input del flusso di lavoro. È consigliabile semplificare il riutilizzo del flusso di lavoro da parte di un altro utente senza dover specificare troppe impostazioni.
Gli input possono avere diverse proprietà, tra cui:
- Il nome di input usato per fare riferimento all'input nelle definizioni del flusso di lavoro.
- Il tipo di input. Gli input supportano valori stringa, numero e booleani.
- Il valore predefinito dell'input, che è facoltativo. Se non si specifica un valore predefinito, è necessario specificare un valore quando il flusso di lavoro viene usato in un flusso di lavoro chiamante.
I segreti hanno nomi, ma non hanno tipi o valori predefiniti.
Nell'esempio il flusso di lavoro definisce un input stringa obbligatorio denominato environmentType
e tre segreti obbligatori denominati AZURE_CLIENT_ID
, AZURE_TENANT_ID
e AZURE_SUBSCRIPTION_ID
.
Nel flusso di lavoro si usa una sintassi speciale per fare riferimento al valore del parametro, come in questo esempio:
jobs:
say-hello:
runs-on: ubuntu-latest
steps:
- run: |
echo Hello ${{ inputs.environmentType }}!
Il valore per gli input viene passato a un flusso di lavoro chiamato usando la parola chiave with
. È necessario definire i valori per ogni input all'interno della sezione with
. Non è possibile usare la parola chiave env
per fare riferimento alle variabili di ambiente di un flusso di lavoro. I valori dei segreti vengono passati a un flusso di lavoro chiamato usando la parola chiave secrets
.
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
job-test:
uses: ./.github/workflows/script.yml
with:
environmentType: Test
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
job-production:
uses: ./.github/workflows/script.yml
with:
environmentType: Production
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
Usare le identità dei carichi di lavoro dei flussi di lavoro chiamati
Quando si usano i flussi di lavoro chiamati, spesso si definiscono alcune azioni di distribuzione in più file di definizione del flusso di lavoro. È necessario concedere l'autorizzazione al flusso di lavoro chiamante, il che garantisce che ogni flusso di lavoro chiamato sia in grado di accedere all'identità del flusso di lavoro e di eseguire l'autenticazione in Azure:
on:
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
job-test:
uses: ./.github/workflows/script.yml
with:
environmentType: Test
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
job-production:
uses: ./.github/workflows/script.yml
with:
environmentType: Production
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
Condizioni
È possibile usare le condizioni del flusso di lavoro per specificare se un passaggio o un processo deve essere eseguito in base a una regola specificata. È possibile combinare input e condizioni del flusso di lavoro per personalizzare il processo di distribuzione per più situazioni.
Si supponga, ad esempio, di definire un flusso di lavoro che esegue i passaggi di script. Si prevede di riutilizzare il modello per ogni ambiente. Quando si distribuisce l'ambiente di produzione, si vuole eseguire un altro passaggio. Ecco come ottenere questo risultato usando la condizione if
nel passaggio:
jobs:
say-hello:
runs-on: ubuntu-latest
steps:
- run: |
echo Hello ${{ inputs.environmentType }}!
- run: |
echo This step only runs for production deployments.
if: inputs.environmentType == 'Production'
La condizione in questo caso si traduce in: se il valore del parametro environmentType è uguale a "Production", eseguire il passaggio .
Anche se le condizioni aggiungono flessibilità al flusso di lavoro, se sono troppe possono complicare il flusso di lavoro e rendere più difficile la comprensione. Se si hanno molte condizioni in un flusso di lavoro chiamato, è consigliabile riprogettare il flusso di lavoro.
Usare anche commenti YAML per spiegare le condizioni usate e qualsiasi altro aspetto del flusso di lavoro che potrebbe richiedere una spiegazione più approfondita. I commenti semplificano la comprensione e l'uso del flusso di lavoro in futuro. In tutti gli esercizi di questo modulo sono presenti alcuni commenti YAML di esempio.