Seamless Development with Dev Containers for Bicep

Using Dev Container setup for Bicep

Kasun Rajapakse
7 min readFeb 15, 2024

1. Introduction

Azure Bicep is a domain-specific language for infrastructure provisioning (Infrastructure as Code). Azure Bicep is a success for the ARM template and uses easy-to-understand language for code definition.

Dev Containers encapsulate development environments in Docker containers, avoiding the “it works on my machine” problem and assuring team consistency. These containers standardize all developers' tools, libraries, and configurations, speeding up setup and environment preparation. Dev Containers automates environment setup with a version-controlled devcontainer.json file, letting developers work on projects fast and from any workstation. This improves collaboration flexibility, software development, testing, and deployment reliability and predictability, especially for remote teams.

2. The Role of Dev Containers in Development

Dev Container configuration ensures that all developers working on the project have the same development environment, regardless of their local computer configuration. The Dev Container may be launched on any system that supports Docker, making it a very adaptable tool for developers.

Benefits

  • Consistency Across Development Teams
  • Quick and Easy Setup
  • Isolation from Local Environment
  • Flexibility and Portability
  • Integration with Development Tools
  • Customisation and Scalability

3. Setting Up Your Development Environment

In this section, let's walk through how to configure Dev Containers and what prerequisites are needed to start with Dev Containers.

Integration of Dev Containers with Visual Studio Code

Dev Containers can be integrated with VS code with the installation of the extension. You need Docker installed on a local computer to work with Dev Containers.

You can follow the below link to install the VS Code extension or search from the extension section in the VS code.

Figure 1 — Dev Container Extension

As the first step for dev containers, we must create a devcontainer.json file in the project's root under the folder .devcontainer. This can be easily created with the VS Code extension. We can follow the step-by-step process of creating the .devcontainer.json file. Let’s look at how to create the dev container configuration file.

After installing the extension for the dev container, it includes VS Code commands as follows.

Figure 2 — Dev Container Commands

Create a Dev Container configuration file

Let’s look at creating a configuration file using VS Code dev container commands.

Open the command palette as below

Figure 3 — Command Palette in VS Code

Select the command to create the configuration file

Figure 4 — Command to create a configuration file

Select where you would like to create the configuration file

Figure 5 — Select the configuration file location

Select the Configuration template for Bicep I selected C# because the Bicep language server depends on C# SDK.

Figure 6 — Select the template

Select the .NET version required. I used the latest version available.

Figure 7 — Select the .Net version

Under the features, you can add additional tools or configurations you require. This blog focuses on Bicep, so I searched for Bicep and selected Bicep. We will add another feature called common utilities.

Figure 8— Add Bicep feature
Figure 9 — Add common utilities

After that, select ok in the above image to create the configuration file. Following is an example configuration file.

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "C# (.NET)",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0",
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {},
"ghcr.io/rchaganti/vsc-devcontainer-features/azurebicep:1": {}
}

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [5000, 5001],
// "portsAttributes": {
// "5001": {
// "protocol": "https"
// }
// }

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "dotnet restore",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

Run Dev Container using the configuration file

Now, we build the configuration file, and let's see how we can run the Dev Container.

We can use the VS Code command to create a new Dev Container environment using the file we created.

Figure 10 — Run Dev Container environment

In the background, Dev Container will spin up a container as below and mound the volume to the container as a bind mount.

Figure 11 — Dev Container running
Figure 12 — bind mount of local storage.

In the list of extensions in the Dev container, you can see the Bicep extension was installed.

Figure 13 — Bicep extension installed in Dev Container

As shown below, you can work on an isolated environment configured specially for Bicep.

Figure 14 — Isolated environment for Bicep

Real-world Applications

In this example, I showed you how to use Dev Container with Bicep, but it's not limited to Bicep. We can use Dev Containers in a wide range of real-world use cases. Following are a few of those use cases.

Example 1: Multi-Environment Cloud Infrastructure Deployment

A software company is working on deploying a complex cloud infrastructure across multiple Azure environments (development, staging, production). Each environment requires specific configurations and dependencies to deploy resources like virtual machines, networking components, and databases.

Challenge: Ensuring the Bicep templates run consistently across different developers’ machines and CI/CD pipelines, avoiding the “it works on my machine” problem.

Solution: The team uses Dev Containers to put the Bicep CLI and all the necessary tools inside a Docker container. This setup ensures that everyone uses the same versions and settings of the tools, no matter what their local work environment is like. The containerized environment works well with their CI/CD process, so scripts that run fine locally will also run correctly in the pipeline.

Example 2: Collaborative Development of Azure Kubernetes Service (AKS) Infrastructure

A development team is tasked with creating a scalable and secure infrastructure for a new application hosted on Azure Kubernetes Service (AKS).

Challenge: Working collaboratively on infrastructure code while ensuring all contributors have the same tool and dependency versions, such as the Bicep CLI, Azure CLI, and kubectl.

Solution: Using Dev Containers, the team creates a shared development environment with all necessary tools pre-configured. This strategy expedites new team members' onboarding process and enables real-time collaboration using uniform tooling. Any upgrades or additions to the toolset are done within the Dev Container setup and immediately shared with the team, ensuring that everyone is up to date.

Example 3: Educational Workshops and Training

An Azure training provider offers workshops on how to use Bicep for IaC. The workshops draw participants with a wide range of technical backgrounds and levels of experience with Azure and containerization technologies.

Challenge: Quickly onboarding participants to a complex development environment, ensuring they can focus on learning Bicep without worrying about setup issues.

Solution: Dev Containers are used by the training source to set up a development environment ready for each participant. This environment has the Bicep CLI, the Azure CLI, and other necessary tools, so students can start writing Bicep code and deploying it to Azure right away during the training. This setup makes learning easier by eliminating technical problems and shows how to manage work environments best.

Conclusion

Finally, integrating Dev Containers with Bicep solves many cloud infrastructure development issues. Dev Containers encapsulate the development environment in containers, making it uniform, scalable, and reproducible across computers and platforms. Teams working on complicated Azure deployments benefit from this consistency, eliminating the “it works on my machine” syndrome.

Dev Containers’ isolation and versatility, along with Bicep’s declarative simplicity, streamline development. Knowing that their development and testing environment is the same as production allows developers to quickly onboard new projects, interact with team members, and confidently deploy infrastructure. The ease of setup and interaction with common IDEs lets developers write code instead of setting environments, increasing productivity.

Learn More

--

--

Anything related to Azure, AWS, GCP, Containers & Kubernetes. Technology enthusiastic, Learner, Blogger