{"id":50385149,"url":"https://github.com/stackhpc/magnum-terraform","last_synced_at":"2026-05-30T14:31:02.947Z","repository":{"id":186725182,"uuid":"675641700","full_name":"stackhpc/magnum-terraform","owner":"stackhpc","description":null,"archived":false,"fork":false,"pushed_at":"2023-08-22T16:14:25.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-14T22:50:20.900Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stackhpc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-07T11:45:08.000Z","updated_at":"2023-08-07T11:49:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"dd76c1e8-8c20-4f78-beb9-3415a3cd2afb","html_url":"https://github.com/stackhpc/magnum-terraform","commit_stats":null,"previous_names":["stackhpc/magnum-terraform"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stackhpc/magnum-terraform","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackhpc%2Fmagnum-terraform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackhpc%2Fmagnum-terraform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackhpc%2Fmagnum-terraform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackhpc%2Fmagnum-terraform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stackhpc","download_url":"https://codeload.github.com/stackhpc/magnum-terraform/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackhpc%2Fmagnum-terraform/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33696681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T14:31:02.849Z","updated_at":"2026-05-30T14:31:02.920Z","avatar_url":"https://github.com/stackhpc.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"Magnum Tour\n===========\n\nThis example goes through creating a magnum cluster using Terraform and connecting to it. We assume the existence of a template created by your OpenStack operator.\n\nNext we give you an overview of the built-in monitoring and load balancing.\n\nFinally we look at exposing servers via ingress.\n\nInstall dependencies\n--------------------\n\nFirst ensure you have a working OpenStack CLI environment, that includes both python-openstackclient and python-magnumclient. This needs to be run on a Linux environment (such as Windows WSL) that has access to the OpenStack APIs.\n\n    virtualenv ~/.venv\n    . ~/.venv/bin/activate\n    pip install -U pip\n    pip install -U python-openstackclient python-magnumclient python-octaviaclient\n\nTo access Kubernetes, you will need to install `kubectl` on a machine that will have access to the Kubernetes API. \n\n    curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl\n    chmod +x ./kubectl\n    sudo mv ./kubectl /usr/local/bin/kubectl\n\nYou'll also need to download v0.14 release of terraform using the script below (check \u003chttps://www.terraform.io/downloads.html\u003e for the most recent version):\n\n    VERSION=0.14.9\n    curl -L https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_linux_amd64.zip --output terraform.zip\n    unzip terraform.zip\n    rm terraform.zip\n    sudo mv terraform /usr/local/bin/terraform\n\nLast but not the least, you'll need to install `helm` v3 client by running the snippet below if using a Linux box (or  check \u003chttps://helm.sh/docs/intro/install/\u003e for altertive instructions):\n\n    VERSION=v3.5.2\n    curl -L https://get.helm.sh/helm-$VERSION-linux-amd64.tar.gz --output helm.tar.gz\n    mkdir -p tmp\n    tar -xzf helm.tar.gz -C tmp/\n    sudo mv tmp/linux-amd64/helm /usr/local/bin/helm\n    rm -rf helm.tar.gz tmp\n\nNOTE: Ensure that `/usr/local/bin` is in your `PATH` variables. A quick way to check this is by running `echo $PATH` in your terminal.\n\nCreating a Kubernetes cluster\n-----------------------------\n\nWhile you can create your cluster via the Horizon web interface for OpenStack, we recommend using Terraform to create, resize and destroy your k8s clusters. In this repo we include an example Terraform module to make it easier for you to try using Magnum.\n\nTo access OpenStack APIs using the CLI you can create application credentials using OpenStack Horizon (ensuring to click the button marked as dangerous to allow magnum to create credentials that are passed to Kubernetes) that are downloaded as a clouds.yaml file. For more details please see: \u003chttps://docs.openstack.org/python-openstackclient/latest/configuration/index.html\u003e\n\nTo check you have the CLI working, do something like this to test the CLI is working correctly:\n\n    cp ~/Downloads/clouds.yml .\n    export OS_CLOUD=openstack\n    openstack server list\n    openstack flavor list\n    openstack coe cluster template list\n\nTo create the cluster, create your k8s cluster using OpenStack Magnum as follows:\n\n    cd magnum-tour/\n    terraform init # first time only\n    terraform plan\n    terraform apply\n\nIt will produce a snippet to set your `KUBECONFIG` variable that you can copy and paste into your terminal. You can use this to tell kubectl where your cluster lives:\n\n    export KUBECONFIG=~/.kube/magnum-tour/config\n    kubectl version\n    kubectl get all -A\n\nIf you are not using Terraform, you can call the same OpenStack CLI command that Terraform uses to get hold of the kubectl config file:\n\n    openstack coe cluster list\n    openstack coe cluster config \u003cname-of-your-cluster\u003e\n\nFinally you can delete your cluster via Terraform:\n\n    terraform destroy\n\nNote that the above can only remove what Terraform added. In particular, its possible to leave behind loadbalancers, cinder volumes and manila shares created by cloud-provider-openstack if you do not first remove all the artifacts deployed on your Kubernetes cluster.\n\nMonitoring\n----------\n\nMagnum setups up Prometheus and Grafana to monitor your cluster. You can access it via kubectl port forwarding:\n\n    kubectl port-forward -n kube-system svc/magnum-grafana 9000:80\n\nThat will allow you to access it via \u003chttp://localhost:9000\u003e with the default user:admin password:admin combination. Allowing you to change the password to something better before exposing it outside the cluster.\n\nIn a similar way you can access the prometheus console and node exporter:\n\n    kubectl port-forward -n kube-system svc/magnum-prometheus-operator-prometheus 9090:9090\n\nCluster Networking Overview\n---------------------------\n\nTo see how Magnum sits in your OpenStack project's networking, have a look at your network topology in Horizon, after having created a Kubernetes cluster using Magnum.\n\nMagnum generates a configuration file that tells `kubectl` where to access the Kubernetes API. Typically the API is exposed via an OpenStack Octavia load balancer, that has a public IP address assigned from the Magnum external network. Note the master node also makes use of an etcd loadbalancer to allow for a multi-master setup.\n\nAll the minions and master nodes are connected to a private network that Magnum has created. It has a router that is used to connect out the external network.\n\nExposing services using Load Balancer or Port Forwarding\n--------------------------------------------------------\n\nOnce you cluster is up and running you can create a hello world deployment then expose it as a public service via a load balancer:\n\n    kubectl create deployment hello-node --image=nginx\n    kubectl expose deployment hello-node --type=LoadBalancer --port=80\n    kubectl get service hello-node --watch\n\nOnce the loadbalancer is created, you should see the external IP that you can use to access the hello world web app on port 8080. You can see what is happening to the loadbalancer by calling:\n\n    openstack loadbalancer list\n\nIf you don't want to expose your service via a public floating IP, you can access the service by using `kubectl port-forward`:\n\n    kubectl delete service hello-node\n    kubectl expose deployment hello-node --type=ClusterIP --port=80\n    kubectl port-forward service hello-node 8080:80\n\nWhile the above command is running, you can now access the hello world app in your local browser via \u003chttp://localhost:8080\u003e\n\nTo delete the demo app, you can do the following:\n\n    kubectl delete service hello-node\n    kubectl delete deployment hello-node\n\nExposing services via Ingress\n-----------------------------\n\nIngress allows multiple services to share a single IP address and port combination, similar to how traditional shared web hosting can work. This can help you reduce the number of public IP addresses you consume.\n\nFor this demo we use nginx ingress, however we instal it manually so it makes use of a load-balancer service type.\n\nOnce `helm` is installed, you can run:\n\n    helm repo add stable https://charts.helm.sh/stable\n    helm install -n kube-system ingress stable/nginx-ingress --set rbac.create=true\n\nYou can find more information about install ingress here: \u003chttps://kubernetes.github.io/ingress-nginx/deploy/#using-helm\u003e\n\nFirst we can find out the public IP address given to the ingress controller:\n\n    kubectl --namespace kube-system get services ingress-nginx-ingress-controller --watch\n\nFrom this we can work out a possible way to access services via DNS:\n\n    hello.`kubectl --namespace kube-system get services ingress-nginx-ingress-controller -o jsonpath={.status.loadBalancer.ingress[*].ip}`.nip.io\n\nAt the moment you will get a 404 response from http, and https endpoints associated with the about DNS name. The next step is to make use of ingress to access a service. As an example, lets expose Grafana via ingress:\n\n    cat \u003c\u003cEND | kubectl apply -f -\n    apiVersion: networking.k8s.io/v1\n    kind: Ingress\n    metadata:\n      name: grafana-ingress\n      namespace: kube-system\n      annotations:\n        kubernetes.io/ingress.class: nginx\n    spec:\n        rules:\n          - host: grafana.`kubectl --namespace kube-system get services ingress-nginx-ingress-controller -o jsonpath={.status.loadBalancer.ingress[*].ip}`.nip.io\n            http:\n              paths:\n                - path: /\n                  pathType: Prefix\n                  backend:\n                      service:\n                        name: magnum-grafana\n                        port:\n                          number: 80\n    END\n\nIn a similar way we can add the hello world service on the same IP:\n\n    kubectl create deployment hello-node --image=nginx\n    kubectl expose deployment hello-node --type=ClusterIP --port=80\n\n    cat \u003c\u003cEND | kubectl apply -f -\n    apiVersion: networking.k8s.io/v1\n    kind: Ingress\n    metadata:\n      name: hello-node\n      namespace: default\n      annotations:\n        kubernetes.io/ingress.class: nginx\n    spec:\n        rules:\n          - host: hello.`kubectl --namespace kube-system get services ingress-nginx-ingress-controller -o jsonpath={.status.loadBalancer.ingress[*].ip}`.nip.io\n            http:\n              paths:\n                - path: /\n                  pathType: Prefix\n                  backend:\n                      service:\n                        name: hello-node\n                        port:\n                          number: 80\n    END\n\nTo remove the above ingress entries and hello world service:\n\n    kubectl delete ingress hello-node -n default\n    kubectl delete ingress grafana-ingress -n kube-system\n    kubectl delete service hello-node\n    kubectl delete deployment hello-node\n\nIf you want to remove the nginx ingress controller from the system:\n\n    helm delete -n kube-system ingress\n\nNodegroups\n----------\n\nAt present, nodegroups are supported via OpenStack CLI using `python-magnumclient` package.\n\n    openstack coe nodegroup create magnum-tour small --flavor general.v1.small --node-count 1\n    openstack coe nodegroup list magnum-tour\n\nOnce the nodegroup is ready, you will be able to enlist it normally:\n\n    kubectl get nodes\n\nExpected output:\n\n    NAME                                    STATUS   ROLES    AGE     VERSION\n    magnum-tour-7of46hmjcg4g-master-0       Ready    master   4h37m   v1.20.4\n    magnum-tour-7of46hmjcg4g-node-0         Ready    \u003cnone\u003e   4h34m   v1.20.4\n    magnum-tour-small-rswdkdscbobv-node-0   Ready    \u003cnone\u003e   67s     v1.20.4\n\nThis feature allows specific applications to only run on the speficied nodegroups:\n\n    cat \u003c\u003cEND | kubectl apply -f -\n    apiVersion: apps/v1\n    kind: Deployment\n    metadata:\n      name: hello-node\n    spec:\n      replicas: 1\n      selector:\n        matchLabels:\n          component: hello-node\n      template:\n        metadata:\n          labels:\n            component: hello-node\n        spec:\n          affinity:\n            nodeAffinity:\n              requiredDuringSchedulingIgnoredDuringExecution:\n                nodeSelectorTerms:\n                - matchExpressions:\n                  - key: magnum.openstack.org/nodegroup\n                    operator: In\n                    values:\n                    - small\n          containers:\n            - name: hello-node\n              image: nginx\n              ports:\n                - containerPort: 80\n    END\n\nEnlist the pods to show where it got scheduled:\n\n    kubectl get pods -o wide\n\nExpected output:\n\n    NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE                                    NOMINATED NODE   READINESS GATES\n    hello-node-847d646746-dpwhz   1/1     Running   0          20s   10.100.129.193   magnum-tour-small-rswdkdscbobv-node-0   \u003cnone\u003e           \u003cnone\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackhpc%2Fmagnum-terraform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstackhpc%2Fmagnum-terraform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackhpc%2Fmagnum-terraform/lists"}