# 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: ```console sudo snap install microk8s --channel=1.27-strict/stable ``` Add your user to the `snap_microk8s` group: ```console sudo usermod -a -G snap_microk8s $USER newgrp snap_microk8s ``` Add the community repository MicroK8s addon: ```console sudo microk8s addons repo add community https://github.com/canonical/microk8s-community-addons --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. ```console sudo microk8s enable hostpath-storage sudo microk8s enable multus sudo microk8s enable metallb:10.0.0.2-10.0.0.4 ``` ## 2. Bootstrap a Juju controller From your terminal, install Juju. ```console sudo snap install juju --channel=3.4/stable ``` Bootstrap a Juju controller ```console juju bootstrap microk8s ``` ```{note} There is a [bug](https://bugs.launchpad.net/juju/+bug/1988355) 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. ```console sudo snap install terraform --classic ``` ## 4. Deploy Charmed Aether SD-Core On the host machine create a new directory called `terraform`: ```console mkdir terraform ``` Inside newly created `terraform` directory create a `terraform.tf` file: ```console cd terraform cat << EOF > versions.tf terraform { required_providers { juju = { source = "juju/juju" version = ">= 0.12.0" } } } EOF ``` Create a Terraform module containing the SD-Core 5G core network and a router: ```console cat << EOF > main.tf resource "juju_model" "sdcore" { name = "sdcore" } module "sdcore-router" { source = "git::https://github.com/canonical/sdcore-router-k8s-operator//terraform" model = juju_model.sdcore.name depends_on = [juju_model.sdcore] } module "sdcore" { source = "git::https://github.com/canonical/terraform-juju-sdcore//modules/sdcore-k8s" model = juju_model.sdcore.name depends_on = [module.sdcore-router] traefik_config = { routing_mode = "subdomain" } } EOF ``` ```{note} You can get a ready example by cloning [this Git repository](https://github.com/canonical/charmed-aether-sd-core). All necessary files are in the `examples/terraform/getting_started` directory. ``` Initialize Juju Terraform provider: ```console terraform init ``` Deploy SD-Core by applying your Terraform configuration: ```console terraform apply -auto-approve ``` The deployment process should take approximately 15-20 minutes. Monitor the status of the deployment: ```console 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.
It is also expected that `traefik` goes to the error state (related Traefik [bug](https://github.com/canonical/traefik-k8s-operator/issues/361)). Example: ```console ubuntu@host:~$ juju status Model Controller Cloud/Region Version SLA Timestamp sdcore microk8s-localhost microk8s-classic/localhost 3.4.5 unsupported 08:08:50Z App Version Status Scale Charm Channel Rev Address Exposed Message amf 1.4.4 active 1 sdcore-amf-k8s 1.5/edge 707 10.152.183.176 no ausf 1.4.2 active 1 sdcore-ausf-k8s 1.5/edge 520 10.152.183.65 no grafana-agent 0.32.1 waiting 1 grafana-agent-k8s latest/stable 45 10.152.183.221 no installing agent mongodb active 1 mongodb-k8s 6/beta 38 10.152.183.92 no Primary nms 1.0.0 active 1 sdcore-nms-k8s 1.5/edge 580 10.152.183.141 no nrf 1.4.1 active 1 sdcore-nrf-k8s 1.5/edge 580 10.152.183.130 no nssf 1.4.1 active 1 sdcore-nssf-k8s 1.5/edge 462 10.152.183.62 no pcf 1.4.3 active 1 sdcore-pcf-k8s 1.5/edge 512 10.152.183.144 no router active 1 sdcore-router-k8s 1.5/edge 341 10.152.183.218 no self-signed-certificates active 1 self-signed-certificates latest/stable 155 10.152.183.33 no smf 1.5.2 active 1 sdcore-smf-k8s 1.5/edge 590 10.152.183.64 no traefik v2.11.0 waiting 1 traefik-k8s latest/stable 194 10.152.183.198 no installing agent udm 1.4.3 active 1 sdcore-udm-k8s 1.5/edge 489 10.152.183.31 no udr 1.4.1 active 1 sdcore-udr-k8s 1.5/edge 486 10.152.183.82 no upf 1.4.0 active 1 sdcore-upf-k8s 1.5/edge 591 10.152.183.164 no Unit Workload Agent Address Ports Message amf/0* active idle 10.1.10.181 ausf/0* active idle 10.1.10.186 grafana-agent/0* blocked idle 10.1.10.133 grafana-cloud-config: off, logging-consumer: off mongodb/0* active idle 10.1.10.155 Primary nms/0* active idle 10.1.10.174 nrf/0* active idle 10.1.10.151 nssf/0* active idle 10.1.10.136 pcf/0* active idle 10.1.10.146 router/0* active idle 10.1.10.145 self-signed-certificates/0* active idle 10.1.10.141 smf/0* active idle 10.1.10.154 traefik/0* error idle 10.1.10.160 hook failed: "ingress-relation-changed" udm/0* active idle 10.1.10.187 udr/0* active idle 10.1.10.176 upf/0* active idle 10.1.10.169 ``` ## 5. Configure the ingress Get the external IP address of Traefik's `traefik-lb` LoadBalancer service: ```console microk8s.kubectl -n sdcore get svc | grep "traefik-lb" ``` The output should look similar to below: ```console ubuntu@host:~/terraform$ microk8s.kubectl -n private5g get svc | grep "traefik-lb" traefik-lb LoadBalancer 10.152.183.142 10.0.0.4 80:32435/TCP,443:32483/TCP 11m ``` In this tutorial, the IP is `10.0.0.4`. 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 `main.tf` file: ``` :caption: main.tf (...) module "sdcore" { (...) traefik_config = { routing_mode = "subdomain" external_hostname = "10.0.0.4.nip.io" } (...) } (...) ``` Apply new configuration: ```console terraform apply -auto-approve ``` Resolve Traefik error in Juju: ```console juju resolve traefik/0 ``` ## 6. Deploy the gNodeB and a cellphone simulator Inside the `terraform` directory create a new module: ```console cat << EOF > ran.tf resource "juju_model" "ran-simulator" { name = "ran" } module "gnbsim" { source = "git::https://github.com/canonical/sdcore-gnbsim-k8s-operator//terraform" model = juju_model.ran-simulator.name depends_on = [module.sdcore-router] } resource "juju_offer" "gnbsim-fiveg-gnb-identity" { model = juju_model.ran-simulator.name application_name = module.gnbsim.app_name endpoint = module.gnbsim.provides.fiveg_gnb_identity } resource "juju_integration" "gnbsim-amf" { model = juju_model.ran-simulator.name application { name = module.gnbsim.app_name endpoint = module.gnbsim.requires.fiveg_n2 } application { offer_url = module.sdcore.amf_fiveg_n2_offer_url } } resource "juju_integration" "gnbsim-nms" { model = juju_model.sdcore.name application { name = module.sdcore.nms_app_name endpoint = module.sdcore.fiveg_gnb_identity_endpoint } application { offer_url = juju_offer.gnbsim-fiveg-gnb-identity.url } } EOF ``` Initialize Juju Terraform provider: ```console terraform init ``` Apply new configuration: ```console terraform apply -auto-approve ``` Monitor the status of the deployment: ```console juju switch ran watch -n 1 -c juju status --color --relations ``` The deployment is ready when the `gnbsim` application is in the `Active/Idle` state.
Example: ```console ubuntu@host:~/terraform $ juju status Model Controller Cloud/Region Version SLA Timestamp ran microk8s-localhost microk8s/localhost 3.4.3 unsupported 12:18:26+02:00 SAAS Status Store URL amf active local admin/sdcore.amf App Version Status Scale Charm Channel Rev Address Exposed Message gnbsim 1.4.3 active 1 sdcore-gnbsim-k8s 1.5/edge 557 10.152.183.209 no Unit Workload Agent Address Ports Message gnbsim/0* active idle 10.1.194.238 Offer Application Charm Rev Connected Endpoint Interface Role gnbsim gnbsim sdcore-gnbsim-k8s 557 1/1 fiveg_gnb_identity fiveg_gnb_identity provider ``` ## 7. Configure the 5G core network through the Network Management System Retrieve the NMS address: ```console juju switch sdcore juju run traefik/0 show-proxied-endpoints ``` The output should be `http://sdcore-nms.10.0.0.4.nip.io/`. Navigate to this address in your browser. In the Network Management System (NMS), create a network slice with the following attributes: - Name: `default` - MCC: `001` - MNC: `01` - UPF: `upf-external.sdcore.svc.cluster.local:8805` - gNodeB: `sdcore-gnbsim-gnbsim` You should see the following network slice created: ```{image} ../images/nms_network_slice.png :alt: NMS Network Slice :align: center ``` Create a subscriber with the following attributes: - IMSI: `001010100007487` - OPC: `981d464c7c52eb6e5036234984ad0bcf` - Key: `5122250214c33e723a5dd523fc145fc0` - Sequence Number: `16f3b3f70fc2` - Network Slice: `default` - Device Group: `default-default` You should see the following subscriber created: ```{image} ../images/nms_subscriber.png :alt: NMS Subscriber :align: center ``` ## 8. Run the 5G simulation Run the simulation: ```console juju switch ran juju run gnbsim/leader start-simulation ``` The simulation executed successfully if you see `success: "true"` as one of the output messages: ```console 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: 5/5 profiles passed success: "true" ``` ## 9. Destroy the environment Destroy Terraform deployment: ```console terraform destroy -auto-approve ``` ```{note} Terraform does not remove anything from the working directory. If needed, please clean up the `terraform` directory manually by removing everything except for the `main.tf` and `terraform.tf` files. ``` Destroy the Juju controller and all its models: ```console juju kill-controller microk8s-localhost ```