-
-
Save rosskevin/ac85c687f539912cdfdde15245ea5e22 to your computer and use it in GitHub Desktop.
Cluster problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Output, | |
Input, | |
ComponentResource, | |
ComponentResourceOptions, | |
Config, | |
output, | |
} from '@pulumi/pulumi' | |
import * as gcp from '@pulumi/gcp' | |
import * as random from '@pulumi/random' | |
import { Logger } from '@alienfast/logger' | |
import { createKubeconfig } from './createKubeconfig' | |
const log = Logger.get('Cluster') | |
export interface ClusterArgs { | |
readonly config: Config | |
/** | |
* Per-zone initial count | |
*/ | |
readonly initialNodeCount?: Input<number> | |
readonly username?: Input<string> | |
readonly password?: Input<string> | |
/** | |
* Maximum number of nodes in the NodePool. Must be >= min_node_count. | |
*/ | |
readonly maxNodeCount?: Input<number> | |
readonly network: gcp.compute.Network | |
readonly subnetwork: gcp.compute.Subnetwork | |
/** | |
* Match whatever version is in the gcp console. See general readme below regarding versioning and preventing cluster replacement on update. | |
*/ | |
readonly nodeVersion: Input<string> | |
readonly project: Input<string> | |
/** | |
* The location (region) in which the cluster master will be created, as well as the default node location. | |
* | |
* - (optimal production) If you specify a region (such as us-west1), the cluster will be a regional cluster with multiple masters spread | |
* across zones in the region, and with default node locations in those zones as well. | |
* | |
* - (not optimal) If you specify a zone (such as us-central1-a), the cluster will be a zonal cluster with a single cluster master. | |
* | |
* In a regional cluster, cluster master nodes are present in multiple zones in the region. For that reason, regional clusters should be preferred. | |
*/ | |
readonly location: Input<string> // us-central1 | |
} | |
/** | |
* Create a regional cluster with `location`. | |
* | |
* | |
* Updating the cluster master and node pool versions: | |
* - update via gcp console - wait until complete | |
* - `pulumi refresh` - check details to verify then accept | |
* - change Cluster `nodeVersion` to match what was refreshed | |
* - verify no changes with `pulumi preview` | |
* NOTE: make sure this package is compiling with `yarn build -w` when doing the above | |
* | |
* | |
* @see https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters/create | |
* @see https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-cluster#regional | |
* @see https://cloud.google.com/kubernetes-engine/docs/how-to/alias-ips#create | |
*/ | |
export class Cluster extends ComponentResource { | |
// public readonly instance: gcp.container.Cluster | |
public readonly kubeconfig: Output<string> | |
public readonly name: Output<string> | |
// public readonly nodePool: gcp.container.NodePool | |
constructor(name: string, args: ClusterArgs, opts: ComponentResourceOptions) { | |
super('af:pulumi:gcp:Cluster', name, {}, opts) | |
const { | |
config, | |
initialNodeCount = 1, | |
location, | |
maxNodeCount = 50, | |
network, | |
subnetwork, | |
nodeVersion, | |
project, | |
// | |
username = 'root', | |
// Generate a default strong password for the Kubernetes cluster. | |
password = new random.RandomPassword( | |
'password', | |
{ | |
length: 20, | |
special: true, | |
}, | |
{ parent: this }, | |
).result, | |
} = args | |
output(location).apply(l => log.debug(`Creating cluster in ${l}...`)) | |
// const currentVersion = all([project, location]).apply(([p, l]) => | |
// gcp.container.getEngineVersions({ project: p, location: l }).then(v => { | |
// log.info('Versions available:', v) | |
// return v.latestMasterVersion | |
// }), | |
// ) | |
// last input args: | |
// nodeVersion: 'latest', | |
// minMasterVersion: 'latest', | |
// lastOutput = '1.12.6-gke.7' | |
// currentVersion = '1.12.8-gke.10' | |
// latestGkeVersion = '1.13.7-gke.8' | |
const instance = new gcp.container.Cluster( | |
name, | |
{ | |
project, | |
location, | |
// initialNodeCount is the number of nodes to provision per location (default: 1) | |
// don't alter this, alter the node pool args | |
initialNodeCount: 1, | |
// ipAllocationPolicy: { | |
// useIpAliases: true, // creates the cluster with Alias IP addresses | |
// createSubnetwork: true, // enables ip aliasing | |
// }, | |
nodeVersion, | |
masterAuth: { username, password }, | |
// node_version and min_master_version must be set to equivalent values on create | |
minMasterVersion: nodeVersion, | |
// minMasterVersion: 'latest', // leave as whatever it was created with | |
network: network.name, | |
subnetwork: subnetwork.name, | |
// podSecurityPolicyConfig: { enabled: true }, | |
/** | |
* We can't create a cluster with no node pool defined, but we want to only use | |
* separately managed node pools. So we create the smallest possible default | |
* node pool and immediately delete it. | |
*/ | |
removeDefaultNodePool: true, | |
loggingService: 'logging.googleapis.com/kubernetes', | |
monitoringService: 'monitoring.googleapis.com/kubernetes', | |
maintenancePolicy: { | |
dailyMaintenanceWindow: { | |
startTime: '06:00', // UTC - local is midnight (1am on daylight savings) | |
}, | |
}, | |
}, | |
{ | |
parent: this, | |
}, | |
) | |
this.name = instance.name | |
// log.info('nodePool initialNodeCount', initialNodeCount) | |
/** | |
* Create a node pool separately so that alterations do not require a new cluster | |
*/ | |
const nodePool = new gcp.container.NodePool( | |
name, | |
{ | |
cluster: instance.name, | |
project, | |
location, | |
initialNodeCount, // this is also per zone | |
nodeConfig: { | |
// nodeMachineType is the machine type to use for cluster nodes (default: n1-standard-1) | |
// See https://cloud.google.com/compute/docs/machine-types for more details on available machine types. | |
machineType: config.get('machineType') || 'n1-standard-1', | |
metadata: { | |
// Disable legacy metadata APIs that are not v1 and do not enforce internal GCP metadata headers | |
// @see https://www.pulumi.com/docs/guides/crosswalk/kubernetes/control-plane/#recommended-settings | |
'disable-legacy-endpoints': 'true', | |
}, | |
// https://cloud.google.com/sdk/gcloud/reference/container/clusters/create#--scopes | |
oauthScopes: [ | |
'https://www.googleapis.com/auth/compute', | |
'https://www.googleapis.com/auth/cloud-platform', | |
'https://www.googleapis.com/auth/devstorage.read_only', | |
'https://www.googleapis.com/auth/devstorage.full_control', | |
'https://www.googleapis.com/auth/logging.write', | |
'https://www.googleapis.com/auth/monitoring', | |
'https://www.googleapis.com/auth/monitoring.write', | |
'https://www.googleapis.com/auth/pubsub', | |
'https://www.googleapis.com/auth/service.management.readonly', | |
'https://www.googleapis.com/auth/servicecontrol', | |
'https://www.googleapis.com/auth/sqlservice.admin', | |
'https://www.googleapis.com/auth/trace.append', | |
'https://www.googleapis.com/auth/userinfo.email', | |
], | |
}, | |
management: { | |
autoRepair: true, | |
autoUpgrade: true, | |
}, | |
autoscaling: { | |
minNodeCount: 1, // this is per-zone | |
maxNodeCount, // this is per-zone | |
}, | |
}, | |
{ parent: this, dependsOn: [instance] }, | |
) | |
this.kubeconfig = createKubeconfig(instance, project, location) | |
// This component resource has no outputs. | |
this.registerOutputs({}) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as pulumi from '@pulumi/pulumi' | |
import { Cluster } from '@alienfast/pulumi-gcp' | |
import { protect } from '@alienfast/pulumi-common' | |
import { project, region, zone } from './gcp' | |
import { network, subnetwork } from './network' | |
const name = pulumi.getStack() // e.g. development | |
const config = new pulumi.Config('cluster') | |
const zonal = config.getBoolean('zonal') // false or unset for production! | |
// creates a zonal cluster (dev) if only a single node wanted | |
const location = zonal ? zone : region | |
/** | |
* Production settings: | |
* cluster:machineType: n1-standard-1 | |
* cluster:zonal: false | |
* cluster:initialNodeCount: '3' | |
* | |
* Development settings: | |
* cluster:machineType: | |
* cluster:zonal: true | |
* cluster:initialNodeCount: '1' | |
*/ | |
export const cluster = new Cluster( | |
name, | |
{ | |
config, | |
location, | |
network, | |
// set this to the default version from the console on initial creation | |
nodeVersion: '1.13.11-gke.14', | |
project, | |
subnetwork, | |
}, | |
{ dependsOn: [network], protect }, | |
) | |
/** | |
* export the kubeconfig for easy reuse in other stacks | |
*/ | |
// export const kubeconfig = cluster.kubeconfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Type Name Status Info | |
pulumi:pulumi:Stack archetype-infrastructure-production **failed** 1 error; 13 messages | |
└─ af:pulumi:gcp:Cluster production | |
+ └─ gcp:container:Cluster production **creating failed** 1 error | |
Diagnostics: | |
gcp:container:Cluster (production): | |
error: Cannot determine region: set in this resource, or set provider-level 'region' or 'zone'. | |
pulumi:pulumi:Stack (archetype-infrastructure-production): | |
10:36:36 debug Cluster Creating cluster in us-central1-f... | |
error: update failed |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment