Getting started

In this tutorial, we will deploy and run an SD-Core 5G core network using Juju and Terraform. As part of this tutorial, we will also deploy additional components:

  • gNB Simulator: a 5G radio and a cellphone simulator,

  • SD-Core Router: a software router facilitating communication between the core and the Radio Access Network (RAN) to simulate usage of this network.

Both gNB Simulator and SD-Core Router serve only demonstration purposes and shouldn’t be part of production deployments.

To complete this tutorial, you will need a machine which meets the following requirements:

  • A recent x86_64 CPU (Intel 4ᵗʰ generation or newer, or AMD Ryzen or newer)

  • At least 4 cores

  • 8GB of RAM

  • 50GB of free disk space

1. Install MicroK8s

From your terminal, install MicroK8s:

sudo snap install microk8s --channel=1.27-strict/stable

Add your user to the snap_microk8s group:

sudo usermod -a -G snap_microk8s $USER
newgrp snap_microk8s

Add the community repository MicroK8s addon:

sudo microk8s addons repo add community --reference feat/strict-fix-multus

Enable the following MicroK8s addons. We must give MetalLB an address range that has at least 3 IP addresses for Charmed Aether SD-Core.

sudo microk8s enable hostpath-storage
sudo microk8s enable multus
sudo microk8s enable metallb:

2. Bootstrap a Juju controller

From your terminal, install Juju.

sudo snap install juju --channel=3.4/stable

Bootstrap a Juju controller

juju bootstrap microk8s


There is a bug in Juju that occurs when bootstrapping a controller on a new machine. If you encounter it, create the following directory: mkdir -p /home/ubuntu/.local/share

3. Install Terraform

From your terminal, install Terraform.

sudo snap install terraform --classic

4. Create Terraform module

On the host machine create a new directory called terraform:

mkdir terraform

Inside newly created terraform directory create a file:

cd terraform
cat << EOF >
terraform {
  required_providers {
    juju = {
      source  = "juju/juju"
      version = ">= 0.11.0"

Create a Terraform module containing the SD-Core 5G core network, 5G radio and a cellphone simulator and a router:

cat << EOF >
resource "juju_model" "sdcore" {
  name = "sdcore"

module "sdcore-router" {
  source = "git::"

  model_name =
  depends_on = [juju_model.sdcore]

module "sdcore" {
  source = "git::"

  model_name =
  create_model = false

  traefik_config = {
    routing_mode = "subdomain"

  depends_on = [module.sdcore-router]

module "gnbsim" {
  source = "git::"

  model_name =
  depends_on = [module.sdcore-router]

resource "juju_integration" "gnbsim-amf" {
  model =

  application {
    name     = module.gnbsim.app_name
    endpoint = module.gnbsim.fiveg_n2_endpoint

  application {
    name     = module.sdcore.amf_app_name
    endpoint = module.sdcore.fiveg_n2_endpoint

resource "juju_integration" "gnbsim-nms" {
  model =

  application {
    name     = module.gnbsim.app_name
    endpoint = module.gnbsim.fiveg_gnb_identity_endpoint

  application {
    name     = module.sdcore.nms_app_name
    endpoint = module.sdcore.fiveg_gnb_identity_endpoint


You can get a ready example by cloning this Git repository. All necessary files are in the examples/terraform/getting_started directory.

5. Deploy SD-Core

Initialize Juju Terraform provider:

terraform init

Deploy SD-Core by applying your Terraform configuration:

terraform apply -auto-approve

The deployment process should take approximately 15-20 minutes.

Monitor the status of the deployment:

juju switch sdcore
watch -n 1 -c juju status --color --relations

The deployment is ready when all the charms are in the Active/Idle state. It is normal for grafana-agent to remain in waiting state. Example:

ubuntu@host:~$ juju status
Model    Controller          Cloud/Region        Version  SLA          Timestamp
sdcore   microk8s-localhost  microk8s/localhost  3.4.0    unsupported  13:40:12+01:00

App                       Version  Status   Scale  Charm                         Channel             Rev  Address          Exposed  Message
amf                                active       1  sdcore-amf-k8s                1.5/edge            57   no
ausf                               active       1  sdcore-ausf-k8s               1.5/edge            40   no
gnbsim                             active       1  sdcore-gnbsim-k8s             1.5/edge            43   no
grafana-agent             0.32.1   waiting      1  grafana-agent-k8s             latest/stable       44   no       installing agent
mongodb                            active       1  mongodb-k8s                   6/beta              36   no       Primary
nms                                active       1  sdcore-nms-k8s                1.5/edge            26   no
nrf                                active       1  sdcore-nrf-k8s                1.5/edge            62   no
nssf                               active       1  sdcore-nssf-k8s               1.5/edge            37   no
pcf                                active       1  sdcore-pcf-k8s                1.5/edge            32   no
router                             active       1  sdcore-router-k8s             1.5/edge            33    no
self-signed-certificates           active       1  self-signed-certificates      1.5/edge            33   no
smf                                active       1  sdcore-smf-k8s                1.5/edge            37   no
traefik                   2.10.4   active       1  traefik-k8s                   latest/stable      148         no
udm                                active       1  sdcore-udm-k8s                1.5/edge            35   no
udr                                active       1  sdcore-udr-k8s                1.5/edge            31    no
upf                                active       1  sdcore-upf-k8s                1.5/edge            64   no
webui                              active       1  sdcore-webui-k8s              1.5/edge            23   no

Unit                         Workload  Agent  Address      Ports  Message
amf/0*                       active    idle
ausf/0*                      active    idle
gnbsim/0*                    active    idle
grafana-agent/0*             blocked   idle         logging-consumer: off, grafana-cloud-config: off
mongodb/0*                   active    idle         Primary
nms/0*                       active    idle
nrf/0*                       active    idle
nssf/0*                      active    idle
pcf/0*                       active    idle
router/0*                    active    idle
self-signed-certificates/0*  active    idle
smf/0*                       active    idle
traefik/0*                   active    idle
udm/0*                       active    idle
udr/0*                       active    idle
upf/0*                       active    idle
webui/0*                     active    idle

6. Configure the ingress

Get the IP address of the Traefik application:

juju status traefik

In this tutorial, the IP is Please note it, as we will need it in the next step.

Configure Traefik to use an external hostname. To do that, edit traefik_config in the file:

module "sdcore" {
  traefik_config = {
    routing_mode      = "subdomain"
    external_hostname = ""

Apply new configuration:

terraform apply -auto-approve

Retrieve the NMS address:

juju run traefik/0 show-proxied-endpoints

The output should be Navigate to this address in your browser.

7. Configure the 5G core network through the Network Management System

In the Network Management System (NMS), create a network slice with the following attributes:

  • Name: default

  • MCC: 208

  • MNC: 93

  • UPF: upf-external.sdcore.svc.cluster.local:8805

  • gNodeB: sdcore-gnbsim-gnbsim

You should see the following network slice created:

NMS Network Slice

Create a subscriber with the following attributes:

  • IMSI: 208930100007487

  • OPC: 981d464c7c52eb6e5036234984ad0bcf

  • Key: 5122250214c33e723a5dd523fc145fc0

  • Sequence Number: 16f3b3f70fc2

  • Network Slice: default

  • Device Group: default-default

You should see the following subscriber created:

NMS Subscriber

8. Run the 5G simulation

Run the simulation:

juju run gnbsim/leader start-simulation

The simulation executed successfully if you see success: "true" as one of the output messages:

ubuntu@host:~$ juju run gnbsim/leader start-simulation
Running operation 1 with 1 task
  - task 2 on unit-gnbsim-0

Waiting for task 2...
info: run juju debug-log to get more information.
success: "true"

9. Destroy the environment

Destroy Terraform deployment:

terraform destroy -auto-approve


Terraform does not remove anything from the working directory. If needed, please clean up the terraform directory manually by removing everything except for the and files.

Destroy the Juju controller and all its models:

juju kill-controller microk8s-localhost