Github Action with Bicep

When deploying infrastructure as code I would absolutely recommend deploying it directly from github and that’s where the github action comes in to play.
Github action is basically deploying your code and this article is about how you can create a github action and deploy your (in this article bicep code).

I will use OpenID to connect to Azure you can read more about it here:
https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-azure

  1. So, to start go to Azure Active Directory, App registrations and klick New registration
  2. Give it a meaningful name (for this example i will use bicep-scepman-sp)
  3. Go to Certificates & secrets, Federated credentials
  4. Add at least 2 federated credentials with federated credential scenario: Github Actions deploying Azure resources.
    • Create the first credential as the following example.
      If you are in a github organization, write down that organization.
    • Create the second credential as the following example.
  5. Now we need to add the RBAC roles that the new application registration/service principal needs to deploy your code/infrastructure. always try to use the principle of least access.
    But in this example, I added.
    • Contributor
    • User Access Administrator
  6. Now that you have your application registration/service principal navigate to your github repo and open Settings, Secrets, Actions and add those 3 secrets:
    • AZURE_CLIENT_ID = Your application registration (Application (client) ID).
    • AZURE_SUBSCRIPTION_ID = Subscription where you’re going to deploy.
    • AZURE_TENANT_ID = Your Azure tenant id.
  7. Now in your repo create the following folder structure: .github/workflows/
    You can see how it should look at repo:
  8. Copy the bicep-deploy.yml to your repo and place it in folder .github/workflows/ (as it does in this repo)
  9. Open the file bicep-deploy.yml and change
    • paths to your path
    • az deployment group what-if -g (yourrg) –name rollout-$deploytime -f (to where you have located your file/files)
    • az deployment group Create -g (yourrg) –name rollout-$deploytime -f (to where you have located your file/files)
    • Change to your resource group (-g)
  10. The lines you need to change on bicep-deploy.yml:
    • 10 – bicep-deploy-1
    • 16 – bicep-deploy-1
    • 48 – resource group and bicep-deploy-1
    • 57 – resource group and bicep-deploy-1
# This is a basic workflow to help you get started with github Actions

name: bicep-deploy

# Controls when the workflow will run
on:
  workflow_dispatch:
  pull_request: 
    paths:
     - 'bicep-deploy-1/**' ## Change this to your deployment where your files is located
    types: [opened, reopened, edited, synchronize]
    branches:    
      - 'main'
  push:
    paths:
     - 'bicep-deploy-1/**' ## Change this to your deployment where your files is located
    branches:    
      - 'main'


permissions:
      id-token: write
      contents: read

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "Bicep-Whatif-OR-Create"
  Bicep-Whatif-OR-Create:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2      
      - name: Azure Login
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      # Start the Bicep validation      
      - name: Azure Bicep validate what-if
        if: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'  }} # Here we run the what-if on a Pull request or manualy from Github Action
        uses: azure/CLI@v1
        with:
          azcliversion: latest
          inlineScript: |
            az bicep install
            deploytime=$(date +"%m-%d-%y-%H")
            az deployment group what-if -g yourrg --name rollout-$deploytime -f bicep-deploy-1/main.bicep
      - name: Azure Bicep Create via azcli
        id: scepmanbicepdeploy
        if: ${{ github.event_name == 'push' }} # Here we run the bicep create when we push the code to the main branch.
        uses: azure/CLI@v1
        with:
          azcliversion: latest
          inlineScript: |
            deploytime=$(date +"%m-%d-%y-%H")
            az deployment group Create -g yourrg --name rollout-$deploytime -f bicep-deploy-1/main.bicep
# You need to change to your resource group (yourrg) and bicep-deploy-1, bicep-deploy-2 or to bicep-deploy-1 depending on your deployment.
# Or just create your own deployment and copy what you need from this repo.

Now you have a simple Github Action that deploys on a resource group scope.
You can of course scope it to:
az deployment sub create – for subscription
az deployment mg create – for management group

When you deploy new code/future always create a new branch and create a pull request with your new code. This will trigger a what-if action and a confirmation from the pull request when it has run you should confirm the result and confirm the pull request.
When you confirm a bicep create will run and the code will be pushed to the main branch.

Reference:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-github-actions?tabs=userlevel
https://learn.microsoft.com/en-us/cli/azure/deployment?view=azure-cli-latest

Move cloud shell storage

Background info

If you have the same problem as we had with cloud shell storage account scattered all over our azure platform.
This post is about how you can move your cloud shell storage account to a new storage account.
I would recommend that you guys keep it to one or two resource groups to not end up with the same problem anyway.
We can also create a policy with denies the creation of storage account with the automated tag that gets added to the a cloud shell storage account “ms-resource-usage:azure-cloud-shell”

Move the files

Some users might have saved files thus as picture, script, connection strings and so on.
If a user wants to cope the whole cloud shell, drive this is how you could do it.
If a user don’t have anything that he or she wants to save simply follow steps nr 3-4 and 13 (delete the old storage account)

Copy paste cloud shell

  1. Copy the name of the storage account to notepad or something else, you will need it later on.
  2. Open cloud shell select bash and write: df


    The storage account name will be seen as showed in the picture above followed by the file share name.
  3. In the cloud shell write clouddrive unmount and say y as shown in the picture.
  4. Now create a new cloud shell/Storage account in the subscription of you chose and the same for resource group. Name your new Storage account and fileshare to something meaningful. Example: cloudshellyourname
  5. Now verify that the new storage account and file share is created.
  6. When you have verified that the storage account and file share exist, from cloud shell now run clouddrive unmount and say y as shown in the picture shows above again.
  7. In the Azure portal navigate to the old Storage account and open: Open in explorer (if you dont have the application download and install it)
  8. Login to Azure Storage Explorer and navigate to your old Storage account > file share > image and copy the image file.
  9. Now navigate to your new Storage account > file share > image and paste the copied image file.
  10. Replace the image file and Apply to All Conflicts
  11. Now from the portal open cloud shell and attach the newly created storage account
  12. Verify that the files are located in your new storage account/cloud shell. example command dir
  13. Delete the old storage account.

Referense:

https://learn.microsoft.com/en-us/azure/cloud-shell/persisting-shell-storage