A picture worth a thousand words. Source.

sshpass to simplify interaction with the lab. On MacOS that can be done using MacPorts: sudo port install sshpassInstalling all these requirements can be harder than working with devcontainers directly. Feel free to ask questions about optimal setup for your case during or after the session.
# Clone the repository
> git clone https://github.com/ankudinov/vscode-devcontainers-intro.git
# change your working directory
> cd vscode-devcontainers-intro
# download cEOS-lab from arista.com and place it into gitignored_files directory
# the vagrant provisioning will fail if file not found, review and adjust cEOS image name
> ls gitignored_files
cEOS-lab-4.29.2F.tar
# Start Vagrant VM
> vagrant up
# Initiate VSCode Remote SSH session to the VM
> make remote
# You can destroy the lab any time using the following command:
> vagrant destroy
make demo01(image 1)Shift + Command + P on MacOS (image2)

devcontainer.json generated by VSCode# connect to the host VM
vagrant ssh
# find container ID
docker container ls
# inspect the container
docker container inspect <container-ID>
# check mounts section and find the corresponding volume
# inspect the volume
sudo ls -la /var/lib/docker/volumes/<devcontainer-name>/_data

Bonus: start the Flask app and verify if it's functional with curl.
make demo01 (close the previous window first)Open Folder in Container from the command pallettedemo01 folderdevcontainer.json, run python hello_world.py and go build hello_world.goDevelopment container "Features" are self-contained, shareable units of installation code and dev container configuration. The name comes from the idea that referencing one of them allows you to quickly and easily add more tooling, runtime, or library "Features" into your development container for use by you or your collaborators.
+-- feature
| +-- devcontainer-feature.json
| +-- install.sh
| +-- (other files)
Free idea: create Ansible AVD devcontainer feature.
devcontainer.json contains the specification for your devcontainer.devcontainer/devcontainer.json is present in the directory, the VSCode will suggest to open the folder in the devcontainer automatically{
"name": "Python 3",
// it is possible to use `build` instead of image and provide Dockerfile
// pre-build image provides consistent results, but Dockerfile is easy to adjust for specific environment
"image": "mcr.microsoft.com/devcontainers/python:0-3.9"
}
Check full devcontainer.json reference here.
make demo02 to run itindent-rainbow extension will be automatically installed to provide ident highlightsdemo02-devcontainer{
"build": { "dockerfile": "Dockerfile" }, // build the container from Dockerfile
"customizations": { "vscode": { "extensions": [ "ext1", "ext2", ... ] } }, // install VSCode extensions in devcontainer
"runArgs": [ "docker-flag", ... ] // any Docker flags that are not covered by devcontainer.json spec explicitly
}
NOTE: by default
demo02directory will be mounted to your workspace in/workspaces/vscode/demo02by VSCode.
make demo03# switch user to vscode otherwise Ansible will be installed as root
USER vscode
ENV PATH=$PATH:/home/vscode/.local/bin
# install Ansible AVD collection
ENV _AVD_VERSION="3.8.1"
RUN pip3 install "ansible-core>=2.13.1,<2.14.0" \
&& ansible-galaxy collection install arista.avd:==${_AVD_VERSION} \
&& pip3 install -r /home/vscode/.ansible/collections/ansible_collections/arista/avd/requirements.txt
ansible.cfg to everything and things never break!inventory = inventory.yml
filter_plugins = /home/vscode/ansible-avd/plugins/filters
collections_paths = /home/vscode/.ansible/collections/ansible_collections
interpreter_python = /bin/python3
workspace/<something> path can be inconvenient{
"workspaceMount": "source=${localWorkspaceFolder},target=${containerWorkspaceFolder},type=bind",
"workspaceFolder": "${localWorkspaceFolder}"
// workspaceMount - Overrides the default local mount point for the workspace when the container is created
// workspaceFolder - Sets the default path to open when connecting to the container
// ${localWorkspaceFolder} - Path of the local folder, that contains .devcontainer/devcontainer.json
// ${containerWorkspaceFolder} - The path that the workspaces files can be found in the container
}
make demo04install cLab. That can be done by modifying Dockerfile
RUN bash -c "$(curl -sL https://get.containerlab.dev)" -- -v 0.37.1
Add Docker-outside-Docker feature
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
}
Add following runArgs required for cLab to work correctly over Docker-outside-Docker
"runArgs": [
"--network=host", // use the Docker host network stack
"--pid=host", // use the host's PID namespace inside the container, for cLab to see all processes on the system
"--privileged" // gives extended privileges and all capabilities to the container
]
Add aliases to Dockerfile
Install cmdo tool
The notable difference here is that cmdo will be installed with postCreateCommand
"postCreateCommand": "bash -c \"$(curl -sL https://raw.githubusercontent.com/hellt/cmdo/master/get.sh)\""
Commands or scripts can be executed at different devcontainer lifecycle stages. My favorite options are:
Execute make demo05 to start the demo
WARNING: The container proposed here can be used as a backdoor. Check if it's allowed by the security policy before deploying it anywhere.
code tunnel commandmake demo06Mount your local clones to Ansible collections directory inside the container with runArgs or mounts. That's the equivalent to the following construct in Docker:
-v /home/${USER}/temp_git_repos/ansible-avd/ansible_collections/arista/avd/:/home/vscode/.ansible/collections/ansible_collections/arista/avd
Open PR in devcontainer without mounting anything. Can be suitable for a quick test, where you inventory is not required
Dev Containers: Clone GitHub Pull Request in Container Volume coming soonMount your inventory to the container workspace and point AVD install files in the container to the specific branch or fork. Execute make demo07 to test that
THE END
Do not add page number on this slide
Add footer starting from this slide