k8sjs.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import * as k8s from '@pulumi/kubernetes'
  2. import * as k8stypes from '@pulumi/kubernetes/types/input'
  3. import * as pulumi from '@pulumi/pulumi'
  4. /**
  5. * ServiceDeployment is an example abstraction that uses a class to fold together the common pattern of a
  6. * Kubernetes Deployment and its associated Service object.
  7. */
  8. export class ServiceDeployment extends pulumi.ComponentResource {
  9. public readonly deployment: k8s.apps.v1.Deployment
  10. public readonly service: k8s.core.v1.Service
  11. public readonly ipAddress?: pulumi.Output<string>
  12. constructor(name: string, args: ServiceDeploymentArgs, opts?: pulumi.ComponentResourceOptions) {
  13. super('k8sjs:service:ServiceDeployment', name, {}, opts)
  14. const labels = { app: name }
  15. const currentEnv = args.env || []
  16. currentEnv.push({ name: 'GET_HOSTS_FROM', value: 'dns' })
  17. const container: k8stypes.core.v1.Container = {
  18. name,
  19. image: args.image,
  20. resources: args.resources || { requests: { cpu: '100m', memory: '100Mi' } },
  21. env: currentEnv,
  22. ports: args.ports && args.ports.map((p) => ({ containerPort: p })),
  23. }
  24. this.deployment = new k8s.apps.v1.Deployment(
  25. name,
  26. {
  27. spec: {
  28. selector: { matchLabels: labels },
  29. replicas: args.replicas || 1,
  30. template: {
  31. metadata: { labels: labels },
  32. spec: { containers: [container] },
  33. },
  34. },
  35. },
  36. { parent: this }
  37. )
  38. this.service = new k8s.core.v1.Service(
  39. name,
  40. {
  41. metadata: {
  42. name: name,
  43. labels: this.deployment.metadata.labels,
  44. },
  45. spec: {
  46. ports: args.ports && args.ports.map((p) => ({ port: p, targetPort: p })),
  47. selector: this.deployment.spec.template.metadata.labels,
  48. // Minikube does not implement services of type `LoadBalancer`; require the user to specify if we're
  49. // running on minikube, and if so, create only services of type ClusterIP.
  50. type: args.allocateIpAddress ? (args.isMinikube ? 'ClusterIP' : 'LoadBalancer') : undefined,
  51. },
  52. },
  53. { parent: this }
  54. )
  55. if (args.allocateIpAddress) {
  56. this.ipAddress = args.isMinikube ? this.service.spec.clusterIP : this.service.status.loadBalancer.ingress[0].ip
  57. }
  58. }
  59. }
  60. interface EnvironmentType {
  61. name: string
  62. value: string
  63. }
  64. export interface ServiceDeploymentArgs {
  65. image: string
  66. resources?: k8stypes.core.v1.ResourceRequirements
  67. replicas?: number
  68. ports?: number[]
  69. env?: EnvironmentType[]
  70. allocateIpAddress?: boolean
  71. isMinikube?: boolean
  72. }