Skip to content

Instantly share code, notes, and snippets.

@rosskevin
Created December 23, 2019 18:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rosskevin/ac85c687f539912cdfdde15245ea5e22 to your computer and use it in GitHub Desktop.
Save rosskevin/ac85c687f539912cdfdde15245ea5e22 to your computer and use it in GitHub Desktop.
Cluster problem
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({})
}
}
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
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