<h1> Deploying Multiple VMs</h1> <h2>Table of Contents</h2> - [Introduction](#introduction) - [Example](#example) *** ## Introduction We show how to deploy multiple VMs with the Go client. ## Example ```go import ( "context" "fmt" "net" "github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer" "github.com/threefoldtech/tfgrid-sdk-go/grid-client/workloads" "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types" "github.com/threefoldtech/zos/pkg/gridtypes" ) func main() { // Create Threefold plugin client tfPluginClient, err := deployer.NewTFPluginClient(mnemonics, "sr25519", network, "", "", "", 0, true) // Get a free node to deploy freeMRU := uint64(2) freeSRU := uint64(2) status := "up" filter := types.NodeFilter { FreeMRU: &freeMRU, FreeSRU: &freeSRU, Status: &status, } nodeIDs, err := deployer.FilterNodes(tfPluginClient.GridProxyClient, filter) nodeID1 := uint32(nodeIDs[0].NodeID) nodeID2 := uint32(nodeIDs[1].NodeID) // Create a new network to deploy network := workloads.ZNet{ Name: "newNetwork", Description: "A network to deploy", Nodes: []uint32{nodeID1, nodeID2}, IPRange: gridtypes.NewIPNet(net.IPNet{ IP: net.IPv4(10, 1, 0, 0), Mask: net.CIDRMask(16, 32), }), AddWGAccess: true, } // Create new VMs to deploy vm1 := workloads.VM{ Name: "vm1", Flist: "https://hub.grid.tf/tf-official-apps/base:latest.flist", CPU: 2, PublicIP: true, Planetary: true, Memory: 1024, RootfsSize: 20 * 1024, Entrypoint: "/sbin/zinit init", EnvVars: map[string]string{ "SSH_KEY": publicKey, }, IP: "10.20.2.5", NetworkName: network.Name, } vm2 := workloads.VM{ Name: "vm2", Flist: "https://hub.grid.tf/tf-official-apps/base:latest.flist", CPU: 2, PublicIP: true, Planetary: true, Memory: 1024, RootfsSize: 20 * 1024, Entrypoint: "/sbin/zinit init", EnvVars: map[string]string{ "SSH_KEY": publicKey, }, IP: "10.20.2.6", NetworkName: network.Name, } // Deploy the network first err = tfPluginClient.NetworkDeployer.Deploy(ctx, &network) // Load the network using the state loader // this loader should load the deployment as json then convert it to a deployment go object with workloads inside it networkObj, err := tfPluginClient.State.LoadNetworkFromGrid(network.Name) // Deploy the VM deployments dl1 := workloads.NewDeployment("vm1", nodeID1, "", nil, network.Name, nil, nil, []workloads.VM{vm1}, nil) dl2 := workloads.NewDeployment("vm2", nodeID2, "", nil, network.Name, nil, nil, []workloads.VM{vm2}, nil) err = tfPluginClient.DeploymentDeployer.BatchDeploy(ctx, []*workloads.Deployment{&dl1, &dl2}) // Load the VMs using the state loader vmObj1, err := tfPluginClient.State.LoadVMFromGrid(nodeID1, vm1.Name, dl1.Name) vmObj2, err := tfPluginClient.State.LoadVMFromGrid(nodeID2, vm2.Name, dl2.Name) // Print the VMs Yggdrasil IP fmt.Println(vmObj1.YggIP) fmt.Println(vmObj2.YggIP) // Cancel the VM deployments err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl1) err = tfPluginClient.DeploymentDeployer.Cancel(ctx, &dl2) // Cancel the network err = tfPluginClient.NetworkDeployer.Cancel(ctx, &network) } ``` Running this code should result in two VMs deployed on two separate nodes while being on the same network and you should see an output like this: ```bash 300:e9c4:9048:57cf:f4e0:2343:f891:6037 300:e9c4:9048:57cf:6d98:42c6:a7bf:2e3f ```