# 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.31-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.6/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?ref=v1.5" model = juju_model.sdcore.name depends_on = [juju_model.sdcore] } module "sdcore" { source = "git::https://github.com/canonical/terraform-juju-sdcore//modules/sdcore-k8s?ref=v1.5" 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/localhost 3.6.0 unsupported 11:06:36-05:00 App Version Status Scale Charm Channel Rev Address Exposed Message amf 1.5.1 active 1 sdcore-amf-k8s 1.5/stable 834 10.152.183.64 no ausf 1.5.1 active 1 sdcore-ausf-k8s 1.5/stable 645 10.152.183.201 no grafana-agent 0.32.1 blocked 1 grafana-agent-k8s latest/stable 45 10.152.183.80 no logging-consumer: off, grafana-cloud-config: off mongodb active 1 mongodb-k8s 6/stable 61 10.152.183.88 no nms 1.0.0 active 1 sdcore-nms-k8s 1.5/stable 741 10.152.183.20 no nrf 1.5.2 active 1 sdcore-nrf-k8s 1.5/stable 720 10.152.183.158 no nssf 1.5.1 active 1 sdcore-nssf-k8s 1.5/stable 597 10.152.183.247 no pcf 1.5.2 active 1 sdcore-pcf-k8s 1.5/stable 650 10.152.183.92 no router active 1 sdcore-router-k8s 1.5/stable 424 10.152.183.62 no self-signed-certificates active 1 self-signed-certificates latest/stable 155 10.152.183.193 no smf 1.6.2 active 1 sdcore-smf-k8s 1.5/stable 745 10.152.183.53 no traefik 2.11.0 error 1 traefik-k8s latest/stable 199 10.152.183.104 no hook failed: "certificates-relation-changed" udm 1.5.1 active 1 sdcore-udm-k8s 1.5/stable 605 10.152.183.237 no udr 1.6.1 active 1 sdcore-udr-k8s 1.5/stable 597 10.152.183.79 no upf 1.5.0 active 1 sdcore-upf-k8s 1.5/stable 691 10.152.183.251 no Unit Workload Agent Address Ports Message amf/0* active idle 10.1.213.193 ausf/0* active idle 10.1.213.236 grafana-agent/0* blocked idle 10.1.213.248 logging-consumer: off, grafana-cloud-config: off mongodb/0* active idle 10.1.213.252 Primary nms/0* active idle 10.1.213.214 nrf/0* active idle 10.1.213.195 nssf/0* active idle 10.1.213.243 pcf/0* active idle 10.1.213.225 router/0* active idle 10.1.213.231 self-signed-certificates/0* active idle 10.1.213.232 smf/0* active idle 10.1.213.229 traefik/0* error idle 10.1.213.208 hook failed: "certificates-relation-changed" udm/0* active idle 10.1.213.203 udr/0* active idle 10.1.213.250 upf/0* active idle 10.1.213.200 Offer Application Charm Rev Connected Endpoint Interface Role amf amf sdcore-amf-k8s 834 0/0 fiveg-n2 fiveg_n2 provider upf upf sdcore-upf-k8s 685 0/0 fiveg_n3 fiveg_n3 provider ``` ## 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?ref=v1.5" 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.6.0 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.5.0 active 1 sdcore-gnbsim-k8s 1.5/stable 612 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 612 1/1 fiveg_gnb_identity fiveg_gnb_identity provider ``` ## 7. Configure the 5G core network through the Network Management System Retrieve the NMS credentials (`username` and `password`): ```console juju switch sdcore juju show-secret NMS_LOGIN --reveal ``` The output looks like this: ``` csurgu7mp25c761k2oe0: revision: 1 owner: nms label: NMS_LOGIN created: 2024-11-20T10:22:49Z updated: 2024-11-20T10:22:49Z content: password: ',u7=VEE3XK%t' token: "" username: charm-admin-SOOO ``` Retrieve the NMS address: ```console juju run traefik/0 show-proxied-endpoints ``` The output should be `https://sdcore-nms.10.0.0.4.nip.io/`. Navigate to this address in your browser and use the `username` and `password` to login. 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 ```