Insight Tech APAC Blog Logo

Use cases for GitHub Copilot and Bicep

stephentulp
December 21, 2023

9 minutes to read

Bicep Advent Calendar

Introduction

Generative AI is a new and emerging technology that can learn from existing artifacts to generate new, realistic artifacts that reflect the characteristics of the training data. It can produce a variety of novel content, such as images, video, music, speech, text, software code and product designs. Generative AI has the potential to revolutionize the way we write code, debug, and solve coding challenges. Large Language Models (LLMs) are prime examples of generative AI models, as they can generate coherent and contextually relevant text including code, based on the natural language prompts they receive. Generative AI can handle routine tasks such as auto-filling standard functions used in coding, completing coding statements as the developer is typing, and documenting code functionality in a given standard format, based on the developer’s prompt. The benefits of generative AI include faster product development, enhanced customer experience and improved employee productivity. However, it is important to note that generative AI creates artifacts that can be inaccurate or biased, making human validation essential and potentially limiting the time it saves workers.

Lets investigate how we can use GitHub Copilot and GitHub Copilot Chat to address some use cases for Bicep templates and code.

GitHub Copilot

GitHub Copilot is an AI-powered coding assistant developed by GitHub and OpenAI that is is built on the foundation of the GPT (Generative Pre-trained Transformer) technology. This enables it to understand natural language descriptions and generate code based on context to helps write code faster. It is trained on billions of lines of public code, and is also able to adapt to the user’s own code style and context. It is available as a Visual Studio Code extension and can be used in any programming language supported by Visual Studio Code.

GitHub Copilot Chat

GitHub Copilot Chat, currently in Beta is a chat interface that lets you interact with GitHub Copilot, to ask and receive answers to coding-related questions within GitHub.com and supported IDEs. The chat interface provides access to coding information and support without requiring you to navigate documentation or search online forums.

What is needed?

There are a couple of pre-requisites that are needed to be able to use GitHub Copilot and GitHub Copilot Chat.

  • An active GitHub Copilot subscription All users with a GitHub Copilot Individual subscription can also access the GitHub Copilot Chat beta in Visual Studio Code and Visual Studio.
  • GitHub Copilot and Copilot chat is available in Visual Studio Code.

GitHub Copilot Extensions

After you have installed the extensions into Visual Studio Code, you should now see a new chat icon on the left, this will bring up the chat interface.

GitHub Copilot Chat

Use Cases

Here are some of the use cases that I have found useful, these aren’t specifically just for Bicep and can be used for any language that GitHub Copilot supports.

Bicep Documentation

Lets be frank, no one really likes doing documentation. Here are a few examples of how you can use GitHub Copilot to help you with your documentation.

Creating Inline Descriptions

Within the Bicep template we can see the @description tag being recommended for the parameter, almost like how intellisense works. We can use this for each parameter and it will create the description.

GitHub Copilot metadata

We can also use GitHub Copilot chat to create these for the whole document as well, you can see it is using the open file as the reference and give us all of the parameters and their descriptions.

GitHub Copilot Chat metadata

Auto-completion for Bicep Templates

When you are creating a Bicep template you can use GitHub Copilot to help you with the syntax and auto-complete the code for you. This is probably the one that I use the most and it is very helpful to do a lot of the heavy lifting for you.

The following example shows how you can use GitHub Copilot to help you create a resource block for the Microsoft.Network/networkSecurityGroups Resource Provider and whilst not perfect it does give you the basic structure and you can then fill in the rest of the details as required.

autocomplete nsg

GitHub Copilot uses contextual AI as part of its recommendations, meaning it can understand the code being written and determine the follow up recommendations based on that.

The example below shows a complex if statement that is being used for one side of the virtual network peering, this takes in conditions to make sure things exist and then logic to determine if the hub is a traditional hub or a spoke or Azure vWAN hub. Because Copilot knows about the hub to spoke peering module, it can recommend the if condition for the spoke to hub peering side of things.

autocomplete peering

Convert Bicep to Terraform

Next i tried a couple of options to create Terraform code from Bicep, a Bicep template named PublicIp.bicep was used for this example.

@description('Required. The name of the Public IP Address.')
param name string

@description('Optional. Resource ID of the Public IP Prefix object. This is only needed if you want your Public IPs created in a PIP Prefix.')
param publicIPPrefixResourceId string = ''

@description('Optional. The public IP address allocation method.')
@allowed([
  'Dynamic'
  'Static'
])
param publicIPAllocationMethod string = 'Static'

@description('Optional. Name of a public IP address SKU.')
@allowed([
  'Basic'
  'Standard'
])
param skuName string = 'Standard'

@description('Optional. Tier of a public IP address SKU.')
@allowed([
  'Global'
  'Regional'
])
param skuTier string = 'Regional'

@description('Optional. A list of availability zones denoting the IP allocated for the resource needs to come from.')
param zones array = []

@description('Optional. IP address version.')
@allowed([
  'IPv4'
  'IPv6'
])
param publicIPAddressVersion string = 'IPv4'

@description('Optional. The domain name label. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system.')
param domainNameLabel string = ''

@allowed([
  ''
  'NoReuse'
  'ResourceGroupReuse'
  'SubscriptionReuse'
  'TenantReuse'
])
@description('Optional. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN.')
param domainNameLabelScope string = ''

@description('Optional. The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone.')
param fqdn string = ''

@description('Optional. The reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN.')
param reverseFqdn string = ''

@description('Optional. Location for all resources.')
param location string = resourceGroup().location

@description('Optional. Tags of the resource.')
param tags object?

resource publicIpAddress 'Microsoft.Network/publicIPAddresses@2023-04-01' = {
  name: name
  location: location
  tags: tags
  sku: {
    name: skuName
    tier: skuTier
  }
  zones: zones
  properties: {
    dnsSettings: !empty(domainNameLabel) ? {
      domainNameLabel: domainNameLabel
      domainNameLabelScope: domainNameLabelScope
      fqdn: fqdn
      reverseFqdn: reverseFqdn
    } : null
    publicIPAddressVersion: publicIPAddressVersion
    publicIPAllocationMethod: publicIPAllocationMethod
    publicIPPrefix: !empty(publicIPPrefixResourceId) ? {
      id: publicIPPrefixResourceId
    } : null
    idleTimeoutInMinutes: 4
    ipTags: []
  }
}

output resourceGroupName string = resourceGroup().name
output name string = publicIpAddress.name
output resourceId string = publicIpAddress.id
output ipAddress string = contains(publicIpAddress.properties, 'ipAddress') ? publicIpAddress.properties.ipAddress : ''
output location string = publicIpAddress.location

YouTube: Convert Bicep to Terraform using GitHub Copilot Chat

Within in GitHub Copilot chat I asked the question “Convert Bicep to Terraform” , click on the image to see the code output in the video.

Convert Bicep to Terraform using GitHub Copilot Chat

As you can see from the output it looks pretty good to me, whilst I never ran it to see if it deployed correctly, it is a good starting point. I did try some other examples using modules and linked templates, but it didn’t work as well, most likely because the referenced modules weren’t open in the editor.

Conclusion

Like some people I was skeptical about GitHub Copilot and the value it would bring, but after using it for a while I can see the benefits that it brings, specifically for the mundane type of tasks. It is not perfect and you should always review the code that it generates, but it can be a great tool to help you with Bicep templates.

Further Reading