зеркало из https://github.com/Azure/aks-engine.git
add stateful pool support to dcos
This commit is contained in:
Родитель
2c130400c4
Коммит
15ea4a5c2d
|
@ -84,11 +84,12 @@ func usage(errs ...error) {
|
|||
fmt.Fprintf(os.Stderr, "usage: %s ClusterDefinitionFile\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " read the ClusterDefinitionFile and output an arm template")
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
fmt.Fprintf(os.Stderr, "options:")
|
||||
fmt.Fprintf(os.Stderr, "options:\n")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
var templateDirectory = flag.String("templateDirectory", "./parts", "directory containing base template files")
|
||||
var noPrettyPrint = flag.Bool("noPrettyPrint", false, "do not pretty print output")
|
||||
|
||||
func main() {
|
||||
var acsCluster *vlabs.AcsCluster
|
||||
|
@ -128,10 +129,11 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
if template, err = prettyPrintArmTemplate(template); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error pretty printing template %s", err.Error())
|
||||
os.Exit(1)
|
||||
if !*noPrettyPrint {
|
||||
if template, err = prettyPrintArmTemplate(template); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error pretty printing template %s", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Print(template)
|
||||
}
|
||||
|
|
|
@ -25,4 +25,6 @@ const (
|
|||
DefaultFirstConsecutiveStaticIP = "172.16.0.5"
|
||||
// DefaultAgentSubnetTemplate specifies a default agent subnet
|
||||
DefaultAgentSubnetTemplate = "10.%d.0.0/24"
|
||||
// MaxDisks specifies the maximum attached disks to add to the cluster
|
||||
MaxDisks = 4
|
||||
)
|
||||
|
|
|
@ -29,9 +29,10 @@ type AgentPoolProfile struct {
|
|||
Name string `json:"name"`
|
||||
Count int `json:"count"`
|
||||
VMSize string `json:"vmSize"`
|
||||
IsStateless bool `json:"isStateless,omitempty"`
|
||||
DNSPrefix string `json:"dnsPrefix,omitempty"`
|
||||
Ports []int `json:"ports,omitempty"`
|
||||
IsStateful bool `json:"isStateful,omitempty"`
|
||||
DiskSizesGB []int `json:"diskSizesGB,omitempty"`
|
||||
VnetSubnetID string `json:"vnetSubnetID,omitempty"`
|
||||
// subnet is internal
|
||||
subnet string
|
||||
|
@ -68,6 +69,11 @@ func (a *AgentPoolProfile) IsCustomVNET() bool {
|
|||
return len(a.VnetSubnetID) > 0
|
||||
}
|
||||
|
||||
// HasDisks returns true if the customer specified disks
|
||||
func (a *AgentPoolProfile) HasDisks() bool {
|
||||
return len(a.DiskSizesGB) > 0
|
||||
}
|
||||
|
||||
// GetSubnet returns the read-only subnet for the agent pool
|
||||
func (a *AgentPoolProfile) GetSubnet() string {
|
||||
return a.subnet
|
||||
|
|
|
@ -28,10 +28,12 @@ func (m *MasterProfile) Validate() error {
|
|||
if e := validateName(m.DNSPrefix, "MasterProfile.DNSPrefix"); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := validateDNSName(m.DNSPrefix); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := validateName(m.VMSize, "MasterProfile.VMSize"); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -40,6 +42,9 @@ func (a *AgentPoolProfile) Validate() error {
|
|||
if e := validateName(a.Name, "AgentPoolProfile.Name"); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := validatePoolName(a.Name); e != nil {
|
||||
return e
|
||||
}
|
||||
if a.Count < MinAgentCount || a.Count > MaxAgentCount {
|
||||
return fmt.Errorf("AgentPoolProfile count needs to be in the range [%d,%d]", MinAgentCount, MaxAgentCount)
|
||||
}
|
||||
|
@ -58,6 +63,15 @@ func (a *AgentPoolProfile) Validate() error {
|
|||
if e := validateName(a.DNSPrefix, "AgentPoolProfile.DNSPrefix when specifying AgentPoolProfile Ports"); e != nil {
|
||||
return e
|
||||
}
|
||||
if e := validateDNSName(a.DNSPrefix); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
if len(a.DiskSizesGB) > 0 && !a.IsStateful {
|
||||
return fmt.Errorf("Disks were specified on a non stateful cluster named '%s'. Ensure you add '\"isStateful\": true' to the model", a.Name)
|
||||
}
|
||||
if len(a.DiskSizesGB) > MaxDisks {
|
||||
return fmt.Errorf("A maximum of %d disks may be specified. %d disks were specified for cluster named '%s'", MaxDisks, len(a.DiskSizesGB), a.Name)
|
||||
}
|
||||
if len(a.Ports) == 0 && len(a.DNSPrefix) > 0 {
|
||||
return fmt.Errorf("AgentPoolProfile.Ports must be non empty when AgentPoolProfile.DNSPrefix is specified")
|
||||
|
@ -94,6 +108,9 @@ func (a *AcsCluster) Validate() error {
|
|||
if e := agentPoolProfile.Validate(); e != nil {
|
||||
return e
|
||||
}
|
||||
if a.OrchestratorProfile.OrchestratorType == SWARM && agentPoolProfile.IsStateful {
|
||||
return errors.New("stateful deployments are not supported with SWARM, please let us know if you want this feature")
|
||||
}
|
||||
}
|
||||
if e := a.LinuxProfile.Validate(); e != nil {
|
||||
return e
|
||||
|
@ -141,6 +158,33 @@ func parseCIDR(cidr string) (octet1 int, octet2 int, octet3 int, octet4 int, sub
|
|||
return octet1, octet2, octet3, octet4, subnet, nil
|
||||
}
|
||||
|
||||
func validatePoolName(poolName string) error {
|
||||
// we will cap at length of 12 and all lowercase letters since this makes up the VMName
|
||||
poolNameRegex := `^([a-z][a-z0-9]{0,11})$`
|
||||
re, err := regexp.Compile(poolNameRegex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
submatches := re.FindStringSubmatch(poolName)
|
||||
if len(submatches) != 2 {
|
||||
return fmt.Errorf("pool name '%s' is invalid. A pool name must start with a lowercase letter, have max length of 12, and only have characters a-z0-9", poolName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDNSName(dnsName string) error {
|
||||
dnsNameRegex := `^([a-z][a-z0-9-]{1,13}[a-z0-9])$`
|
||||
re, err := regexp.Compile(dnsNameRegex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
submatches := re.FindStringSubmatch(dnsName)
|
||||
if len(submatches) != 2 {
|
||||
return fmt.Errorf("DNS name '%s' is invalid. The DNS name must contain between 3 and 15 characters. The name can contain only letters, numbers, and hyphens. The name must start with a letter and must end with a letter or a number", dnsName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseIP(ipaddress string) (octet1 int, octet2 int, octet3 int, octet4 int, err error) {
|
||||
// verify cidr format and a /24 subnet
|
||||
// regular expression inspired by http://blog.markhatton.co.uk/2011/03/15/regular-expressions-for-ip-addresses-cidr-ranges-and-hostnames/
|
||||
|
@ -199,7 +243,7 @@ func validateVNET(a *AcsCluster) error {
|
|||
}
|
||||
if isCustomVNET {
|
||||
if a.OrchestratorProfile.OrchestratorType == SWARM {
|
||||
return errors.New("bring your own VNET is not supported with SWARM")
|
||||
return errors.New("bring your own VNET is not supported with SWARM, please let us know if you want this feature")
|
||||
}
|
||||
subscription, resourcegroup, vnetname, _, e := GetVNETSubnetIDComponents(a.MasterProfile.VnetSubnetID)
|
||||
if e != nil {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"orchestratorProfile": {
|
||||
"orchestratorType": "DCOS"
|
||||
},
|
||||
"masterProfile": {
|
||||
"count": 3,
|
||||
"dnsPrefix": "mgmtanhowe0928d",
|
||||
"vmSize": "Standard_D2_v2"
|
||||
},
|
||||
"agentPoolProfiles": [
|
||||
{
|
||||
"name": "agtnodisks1",
|
||||
"count": 1,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"isStateful": true
|
||||
},
|
||||
{
|
||||
"name": "agtnodisks2",
|
||||
"count": 1,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"isStateful": true
|
||||
}
|
||||
],
|
||||
"linuxProfile": {
|
||||
"adminUsername": "azureuser",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"orchestratorProfile": {
|
||||
"orchestratorType": "DCOS"
|
||||
},
|
||||
"masterProfile": {
|
||||
"count": 3,
|
||||
"dnsPrefix": "mgmtanhowe0928g",
|
||||
"vmSize": "Standard_D2_v2"
|
||||
},
|
||||
"agentPoolProfiles": [
|
||||
{
|
||||
"name": "agtnodisks1",
|
||||
"count": 1,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"isStateful": true
|
||||
},
|
||||
{
|
||||
"name": "agent128",
|
||||
"count": 3,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"isStateful": true,
|
||||
"diskSizesGB": [10, 10, 10, 10]
|
||||
},
|
||||
{
|
||||
"name": "agent1public",
|
||||
"count": 3,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"dnsPrefix": "appanhowe0928g",
|
||||
"isStateful": true,
|
||||
"diskSizesGB": [1],
|
||||
"ports": [
|
||||
80,
|
||||
443,
|
||||
8080
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "agtnodisks2",
|
||||
"count": 1,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"isStateful": true
|
||||
},
|
||||
{
|
||||
"name": "agtnodisks3",
|
||||
"count": 1,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"isStateful": true
|
||||
},
|
||||
{
|
||||
"name": "astateless1",
|
||||
"count": 2,
|
||||
"vmSize": "Standard_D2_v2"
|
||||
},
|
||||
{
|
||||
"name": "astateless2",
|
||||
"count": 2,
|
||||
"vmSize": "Standard_D2_v2"
|
||||
}
|
||||
],
|
||||
"linuxProfile": {
|
||||
"adminUsername": "azureuser",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8fhkh3jpHUQsrUIezFB5k4Rq9giJM8G1Cr0u2IRMiqG++nat5hbOr3gODpTA0h11q9bzb6nJtK7NtDzIHx+w3YNIVpcTGLiUEsfUbY53IHg7Nl/p3/gkST3g0R6BSL7Hg45SfyvpH7kwY30MoVHG/6P3go4SKlYoHXlgaaNr3fMwUTIeE9ofvyS3fcr6xxlsoB6luKuEs50h0NGsE4QEnbfSY4Yd/C1ucc3mEw+QFXBIsENHfHfZYrLNHm2L8MXYVmAH8k//5sFs4Migln9GiUgEQUT6uOjowsZyXBbXwfT11og+syPkAq4eqjiC76r0w6faVihdBYVoc/UcyupgH azureuser@linuxvm"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,12 +9,12 @@
|
|||
},
|
||||
"agentPoolProfiles": [
|
||||
{
|
||||
"name": "agentPrivate",
|
||||
"name": "agentprivate",
|
||||
"count": 3,
|
||||
"vmSize": "Standard_D2_v2"
|
||||
},
|
||||
{
|
||||
"name": "agentPublic",
|
||||
"name": "agentpublic",
|
||||
"count": 3,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"dnsPrefix": "appanhowe0927i",
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
},
|
||||
"agentPoolProfiles": [
|
||||
{
|
||||
"name": "agentPrivate",
|
||||
"name": "agentprivate",
|
||||
"count": 3,
|
||||
"vmSize": "Standard_D2_v2"
|
||||
},
|
||||
{
|
||||
"name": "agentPublic",
|
||||
"name": "agentpublic",
|
||||
"count": 3,
|
||||
"vmSize": "Standard_D2_v2",
|
||||
"dnsPrefix": "appanhowe0926i",
|
||||
|
|
|
@ -15,27 +15,28 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
agentOutputs = "agentoutputs.t"
|
||||
agentParams = "agentparams.t"
|
||||
dcosAgentResources = "dcosagentresources.t"
|
||||
dcosAgentVars = "dcosagentvars.t"
|
||||
dcosBaseFile = "dcosbase.t"
|
||||
dcosCustomData173 = "dcoscustomdata173.t"
|
||||
dcosCustomData184 = "dcoscustomdata184.t"
|
||||
dcosMasterResources = "dcosmasterresources.t"
|
||||
dcosMasterVars = "dcosmastervars.t"
|
||||
masterOutputs = "masteroutputs.t"
|
||||
masterParams = "masterparams.t"
|
||||
swarmBaseFile = "swarmbase.t"
|
||||
swarmAgentCustomData = "swarmagentcustomdata.t"
|
||||
swarmAgentResources = "swarmagentresources.t"
|
||||
swarmAgentVars = "swarmagentvars.t"
|
||||
swarmMasterCustomData = "swarmmastercustomdata.t"
|
||||
swarmMasterResources = "swarmmasterresources.t"
|
||||
swarmMasterVars = "swarmmastervars.t"
|
||||
agentOutputs = "agentoutputs.t"
|
||||
agentParams = "agentparams.t"
|
||||
dcosAgentResources = "dcosagentresources.t"
|
||||
dcosAgentResourcesDisks = "dcosagentresourcesdisks.t"
|
||||
dcosAgentVars = "dcosagentvars.t"
|
||||
dcosBaseFile = "dcosbase.t"
|
||||
dcosCustomData173 = "dcoscustomdata173.t"
|
||||
dcosCustomData184 = "dcoscustomdata184.t"
|
||||
dcosMasterResources = "dcosmasterresources.t"
|
||||
dcosMasterVars = "dcosmastervars.t"
|
||||
masterOutputs = "masteroutputs.t"
|
||||
masterParams = "masterparams.t"
|
||||
swarmBaseFile = "swarmbase.t"
|
||||
swarmAgentCustomData = "swarmagentcustomdata.t"
|
||||
swarmAgentResources = "swarmagentresources.t"
|
||||
swarmAgentVars = "swarmagentvars.t"
|
||||
swarmMasterCustomData = "swarmmastercustomdata.t"
|
||||
swarmMasterResources = "swarmmasterresources.t"
|
||||
swarmMasterVars = "swarmmastervars.t"
|
||||
)
|
||||
|
||||
var dcosTemplateFiles = []string{agentOutputs, agentParams, dcosAgentResources, dcosAgentVars, dcosBaseFile, dcosCustomData173, dcosCustomData184, dcosMasterResources, dcosMasterVars, masterOutputs, masterParams}
|
||||
var dcosTemplateFiles = []string{agentOutputs, agentParams, dcosAgentResources, dcosAgentResourcesDisks, dcosAgentVars, dcosBaseFile, dcosCustomData173, dcosCustomData184, dcosMasterResources, dcosMasterVars, masterOutputs, masterParams}
|
||||
var swarmTemplateFiles = []string{agentOutputs, agentParams, masterParams, swarmBaseFile, swarmAgentCustomData, swarmAgentResources, swarmAgentVars, swarmBaseFile, masterOutputs, swarmMasterCustomData, swarmMasterResources, swarmMasterVars}
|
||||
|
||||
// VerifyFiles verifies that the required template files exist
|
||||
|
@ -101,6 +102,9 @@ func GenerateTemplate(acsCluster *vlabs.AcsCluster, partsDirectory string) (stri
|
|||
"GetVNETSubnets": func(addNSG bool) string {
|
||||
return getVNETSubnets(acsCluster, addNSG)
|
||||
},
|
||||
"GetDataDisks": func(profile *vlabs.AgentPoolProfile) string {
|
||||
return getDataDisks(profile)
|
||||
},
|
||||
// inspired by http://stackoverflow.com/questions/18276173/calling-a-template-with-several-pipeline-parameters/18276968#18276968
|
||||
"dict": func(values ...interface{}) (map[string]interface{}, error) {
|
||||
if len(values)%2 != 0 {
|
||||
|
@ -327,6 +331,31 @@ func getSecurityRule(port int, portIndex int) string {
|
|||
}`, port, port, port, vlabs.BaseLBPriority+portIndex)
|
||||
}
|
||||
|
||||
func getDataDisks(a *vlabs.AgentPoolProfile) string {
|
||||
if !a.HasDisks() {
|
||||
return ""
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("\"dataDisks\": [\n")
|
||||
dataDisks := ` {
|
||||
"createOption": "Empty",
|
||||
"diskSizeGB": "%d",
|
||||
"lun": %d,
|
||||
"name": "[concat(variables('%sVMNamePrefix'), copyIndex(),'-datadisk%d')]",
|
||||
"vhd": {
|
||||
"uri": "[concat('http://',variables('storageAccountPrefixes')[mod(add(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('%sStorageAccountOffset')),variables('dataStorageAccountPrefixSeed')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('%sStorageAccountOffset')),variables('dataStorageAccountPrefixSeed')),variables('storageAccountPrefixesCount'))],variables('%sDataAccountName'),'.blob.core.windows.net/vhds/',variables('%sVMNamePrefix'),copyIndex(), '--datadisk%d.vhd')]"
|
||||
}
|
||||
}`
|
||||
for i, diskSize := range a.DiskSizesGB {
|
||||
if i > 0 {
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(dataDisks, diskSize, i, a.Name, i, a.Name, a.Name, a.Name, a.Name, i))
|
||||
}
|
||||
buf.WriteString("\n ],")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func getSecurityRules(ports []int) string {
|
||||
var buf bytes.Buffer
|
||||
for index, port := range ports {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
{
|
||||
"apiVersion": "[variables('apiVersionStorage')]",
|
||||
"copy": {
|
||||
"count": "[variables('agentStorageAccountsCount')]",
|
||||
"count": "[variables('{{.Name}}StorageAccountsCount')]",
|
||||
"name": "loop"
|
||||
},
|
||||
"dependsOn": [
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"name": "[variables('{{.Name}}NSGName')]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{{GetSecurityRules .Ports}}
|
||||
]
|
||||
},
|
||||
"type": "Microsoft.Network/networkSecurityGroups"
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"copy": {
|
||||
"count": "[variables('{{.Name}}Count')]",
|
||||
"name": "loop"
|
||||
},
|
||||
"dependsOn": [
|
||||
{{if .IsCustomVNET}}
|
||||
"[concat('Microsoft.Network/networkSecurityGroups/', variables('{{.Name}}NSGName'))]"
|
||||
{{else}}
|
||||
"[variables('vnetID')]"
|
||||
{{end}}
|
||||
{{if IsPublic .Ports}}
|
||||
,"[variables('{{.Name}}LbID')]"
|
||||
{{end}}
|
||||
],
|
||||
"location": "[resourceGroup().location]",
|
||||
"name": "[concat(variables('{{.Name}}VMNamePrefix'), 'nic-', copyIndex())]",
|
||||
"properties": {
|
||||
{{if .IsCustomVNET}}
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups/', variables('{{.Name}}NSGName'))]"
|
||||
},
|
||||
{{end}}
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipConfigNode",
|
||||
"properties": {
|
||||
{{if IsPublic .Ports}}
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('{{.Name}}LbName'), '/backendAddressPools/',variables('{{.Name}}LbBackendPoolName'))]"
|
||||
}
|
||||
],
|
||||
{{end}}
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[variables('{{.Name}}VnetSubnetID')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "Microsoft.Network/networkInterfaces"
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionStorage')]",
|
||||
"copy": {
|
||||
"count": "[variables('{{.Name}}StorageAccountsCount')]",
|
||||
"name": "loop"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"location": "[variables('storageLocation')]",
|
||||
"name": "[concat(variables('storageAccountPrefixes')[mod(add(copyIndex(),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(copyIndex(),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}AccountName'))]",
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('{{.Name}}VMSize')].storageAccountType]"
|
||||
},
|
||||
"type": "Microsoft.Storage/storageAccounts"
|
||||
},
|
||||
{{if .HasDisks}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionStorage')]",
|
||||
"copy": {
|
||||
"count": "[variables('{{.Name}}StorageAccountsCount')]",
|
||||
"name": "datadiskLoop"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('masterPublicIPAddressName'))]"
|
||||
],
|
||||
"location": "[variables('storageLocation')]",
|
||||
"name": "[concat(variables('storageAccountPrefixes')[mod(add(copyIndex(variables('dataStorageAccountPrefixSeed')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(copyIndex(variables('dataStorageAccountPrefixSeed')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}DataAccountName'))]",
|
||||
"properties": {
|
||||
"accountType": "[variables('vmSizesMap')[variables('{{.Name}}VMSize')].storageAccountType]"
|
||||
},
|
||||
"type": "Microsoft.Storage/storageAccounts"
|
||||
},
|
||||
{{end}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"name": "[variables('{{.Name}}AvailabilitySet')]",
|
||||
"properties": {},
|
||||
"type": "Microsoft.Compute/availabilitySets"
|
||||
},
|
||||
{{if IsPublic .Ports}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"name": "[variables('{{.Name}}IPAddressName')]",
|
||||
"properties": {
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('{{.Name}}EndpointDNSNamePrefix')]"
|
||||
},
|
||||
"publicIPAllocationMethod": "Dynamic"
|
||||
},
|
||||
"type": "Microsoft.Network/publicIPAddresses"
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('{{.Name}}IPAddressName'))]"
|
||||
],
|
||||
"location": "[resourceGroup().location]",
|
||||
"name": "[variables('{{.Name}}LbName')]",
|
||||
"properties": {
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('{{.Name}}LbBackendPoolName')]"
|
||||
}
|
||||
],
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('{{.Name}}LbIPConfigName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('{{.Name}}IPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"inboundNatRules": [],
|
||||
"loadBalancingRules": [
|
||||
{{(GetLBRules .Name .Ports)}}
|
||||
],
|
||||
"probes": [
|
||||
{{(GetProbes .Ports)}}
|
||||
]
|
||||
},
|
||||
"type": "Microsoft.Network/loadBalancers"
|
||||
},
|
||||
{{end}}
|
||||
{
|
||||
"apiVersion": "[variables('apiVersionDefault')]",
|
||||
"copy": {
|
||||
"count": "[variables('{{.Name}}Count')]",
|
||||
"name": "vmLoopNode"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}AccountName'))]",
|
||||
{{if .HasDisks}}
|
||||
"[concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(add(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('{{.Name}}StorageAccountOffset')),variables('dataStorageAccountPrefixSeed')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('{{.Name}}StorageAccountOffset')),variables('dataStorageAccountPrefixSeed')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}DataAccountName'))]",
|
||||
{{end}}
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('{{.Name}}VMNamePrefix'), 'nic-', copyIndex())]",
|
||||
"[concat('Microsoft.Compute/availabilitySets/', variables('{{.Name}}AvailabilitySet'))]"
|
||||
],
|
||||
"location": "[resourceGroup().location]",
|
||||
"name": "[concat(variables('{{.Name}}VMNamePrefix'), copyIndex())]",
|
||||
"properties": {
|
||||
"availabilitySet": {
|
||||
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('{{.Name}}AvailabilitySet'))]"
|
||||
},
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('{{.Name}}VMSize')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('{{.Name}}VMNamePrefix'), 'nic-', copyIndex()))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"osProfile": {
|
||||
"adminUsername": "[variables('adminUsername')]",
|
||||
"computername": "[concat(variables('{{.Name}}VMNamePrefix'), copyIndex())]",
|
||||
"customData": "[base64(concat({{if IsDCOS173}}{{template "dcoscustomdata173.t" dict "DCOSCustomDataPublicIPStr" GetDCOSCustomDataPublicIPStr "DCOSGUID" GetDCOSGUID "RolesString" (GetAgentRolesFileContents .Ports)}}{{else if IsDCOS184}}{{template "dcoscustomdata184.t" dict "DCOSCustomDataPublicIPStr" GetDCOSCustomDataPublicIPStr "DCOSGUID" GetDCOSGUID "RolesString" (GetAgentRolesFileContents .Ports)}}{{end}}))]",
|
||||
"linuxConfiguration": {
|
||||
"disablePasswordAuthentication": "true",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"keyData": "[parameters('sshRSAPublicKey')]",
|
||||
"path": "[variables('sshKeyPath')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"storageProfile": {
|
||||
{{GetDataDisks .}}
|
||||
"imageReference": {
|
||||
"offer": "[variables('osImageOffer')]",
|
||||
"publisher": "[variables('osImagePublisher')]",
|
||||
"sku": "[variables('osImageSKU')]",
|
||||
"version": "[variables('osImageVersion')]"
|
||||
},
|
||||
"osDisk": {
|
||||
"caching": "ReadOnly",
|
||||
"createOption": "FromImage",
|
||||
"name": "[concat(variables('{{.Name}}VMNamePrefix'), copyIndex(),'-osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/',variables('storageAccountPrefixes')[mod(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('storageAccountPrefixes')[div(add(div(copyIndex(),variables('maxVMsPerStorageAccount')),variables('{{.Name}}StorageAccountOffset')),variables('storageAccountPrefixesCount'))],variables('{{.Name}}AccountName')),variables('apiVersionStorage')).primaryEndpoints.blob,'osdisk/', variables('{{.Name}}VMNamePrefix'), copyIndex(), '-osdisk.vhd')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "Microsoft.Compute/virtualMachines"
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
"{{.Name}}StorageAccountOffset": "[mul(variables('agentStorageAccountsCount'),variables('{{.Name}}Index'))]",
|
||||
"{{.Name}}Count": "[parameters('{{.Name}}Count')]",
|
||||
"{{.Name}}StorageAccountOffset": "[mul(variables('maxStorageAccountsPerAgent'),variables('{{.Name}}Index'))]",
|
||||
"{{.Name}}Count": "[parameters('{{.Name}}Count')]",
|
||||
{{if .IsStateful}}
|
||||
"{{.Name}}AvailabilitySet": "[concat('{{.Name}}-availabilitySet-', variables('nameSuffix'))]",
|
||||
"{{.Name}}StorageAccountsCount": "[add(div(variables('{{.Name}}Count'), variables('maxVMsPerStorageAccount')), mod(add(mod(variables('{{.Name}}Count'), variables('maxVMsPerStorageAccount')),2), add(mod(variables('{{.Name}}Count'), variables('maxVMsPerStorageAccount')),1)))]",
|
||||
{{else}}
|
||||
"{{.Name}}StorageAccountsCount": "[variables('maxStorageAccountsPerAgent')]",
|
||||
{{end}}
|
||||
"{{.Name}}NSGID": "[resourceId('Microsoft.Network/networkSecurityGroups',variables('{{.Name}}NSGName'))]",
|
||||
"{{.Name}}NSGName": "[concat(variables('orchestratorName'), '-{{.Name}}-nsg-', variables('nameSuffix'))]",
|
||||
"{{.Name}}VMNamePrefix": "[concat(variables('orchestratorName'), '-{{.Name}}-', variables('nameSuffix'))]",
|
||||
|
|
|
@ -8,14 +8,23 @@
|
|||
"variables": {
|
||||
{{range $index, $agent := .AgentPoolProfiles}}
|
||||
{{template "dcosagentvars.t" .}}
|
||||
{{if .IsStateful}}
|
||||
"{{.Name}}DataAccountName": "[concat(variables('storageAccountBaseName'), 'data{{$index}}')]",
|
||||
{{end}}
|
||||
"{{.Name}}Index": {{$index}},
|
||||
"{{.Name}}AccountName": "[concat(variables('storageAccountBaseName'), 'agnt{{$index}}')]",
|
||||
"{{.Name}}AccountName": "[concat(variables('storageAccountBaseName'), 'agnt{{$index}}')]",
|
||||
{{end}}
|
||||
|
||||
{{template "dcosmastervars.t" .}}
|
||||
},
|
||||
"resources": [
|
||||
{{range .AgentPoolProfiles}}{{template "dcosagentresources.t" .}},{{end}}
|
||||
{{range .AgentPoolProfiles}}
|
||||
{{if .IsStateful}}
|
||||
{{template "dcosagentresourcesdisks.t" .}},
|
||||
{{else}}
|
||||
{{template "dcosagentresources.t" .}},
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{template "dcosmasterresources.t" .}}
|
||||
],
|
||||
"outputs": {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
"adminUsername": "[parameters('linuxAdminUsername')]",
|
||||
"agentStorageAccountsCount": 5,
|
||||
"maxVMsPerPool": 100,
|
||||
"maxVMsPerStorageAccount": 20,
|
||||
"maxStorageAccountsPerAgent": "[div(variables('maxVMsPerPool'),variables('maxVMsPerStorageAccount'))]",
|
||||
"dataStorageAccountPrefixSeed": 97,
|
||||
"apiVersionDefault": "2016-03-30",
|
||||
"apiVersionStorage": "2015-06-15",
|
||||
"masterAvailabilitySet": "[concat(variables('orchestratorName'), '-master-availabilitySet-', variables('nameSuffix'))]",
|
||||
|
|
Загрузка…
Ссылка в новой задаче