EKS Cluster Pulumival néhány perc alatt

Papp Csenge
CodeFactory
Published in
7 min readJan 17, 2024

A projektről

A Pulumi egy gyorsan fejlődő, sok lehetőséget kínáló eszköz. Lehetővé teszi, hogy IaC kódot írjunk olyan népszerű nyelveken, mint a Typescript vagy a Go, sokkal több teret hagyva az egyénibb, rugalmasabb megoldásoknak, mint a Terraform. Első pillantásra olyan koncepciónak tűnt, amivel érdemes kísérletezni. Ezért is hoztunk létre egy kis projektet, amivel egy EKS Clustert telepítettünk ki AWS-re Pulumi segítségével. Ha szeretnéd megnézni a projekt repóját, itt találod.

Ennek a cikknek a célja, hogy bemutassuk ezt a projektet és a Pulumival való munkával kapcsolatos első tapasztalatainkat.

A projekt a következő modulokat tartalmazza:

  • KMS Kulcs
  • VPC (Subnet, Internet Gateway, Nat Gateway, Route table, Elastic IP és Flow Logok)
  • EKS Cluster
  • Helm Release
  • S3 és ECR

Kezdés

Ehhez a projekthez a következőkre lesz szükséged:

Egy új Pulumi projekt indításához létrehozunk egy mappát és futtatjuk benne a pulumi new parancsot. A program meg fog kérdezni néhány alapvető információt, valamint felajánlja, hogy a Pulumi AI prompt-olása alapján hozzon létre egy projektet, ami amúgy egy nagyon érdekes/hasznos új feature, de ezt most kihagyjuk. A sablonok közül válasszuk ki most az aws-typescript-et.

$ pulumi new
Would you like to create a project from a template or using a Pulumi AI prompt? template
Please choose a template (38/221 shown):
aws-typescript A minimal AWS TypeScript Pulumi program
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.
project name (new-project):

A projekt felépítése

Olyan struktúrát akartunk létrehozni, aminek részletei jövőbeli projektekben is újrafelhasználhatóak lesznek, ezét modulokat használtunk az AWS erőforrásokhoz és Pulumi stack config fájlokat az erőforrások attribútumainak változóként való tárolásához. Így ha később változtatni szeretnénk, csak a konfigurációs fájlokat kell majd módosítanunk. Ez sokkal tisztábbá és egyszerűbbé teszi a projekt kezelését.

mappaszerkezet

A Pulumi aws-typscript sablonja mellett a projektnek része még egy mappa a Github workflow-knak. Ebben hoztuk létre a projekt kitelepítéséhez szükséges pipeline-t.

A projekt konfigurálása

Ahhoz, hogy ez a részt megértsük, előszöt beszélnünk kell kicsit a Pulumi Stacks fogalmáról. A Pulumi rendszert biztosít a különböző környezetek, például a development és production kezelésére stackek formájában. Ez hasonló a Terragrunt megközelítéséhez, amely ugyanazon infrastruktúra különböző környezeteit kezeli. Ebben az esetben azonban nem kell kétszer ugyanazt a mappastruktúrát létrehozni. Egyszerűen kezelhetjük az erőforrások attribútumait a Stack konfigurációs fájljában. A Stackeket látszanak a Pulumi vizuális felhasználói felületén vagy lekérhetők a pulumi stack ls paranccsal.

NAME  LAST UPDATE  RESOURCE COUNT  URL
dev 5 days ago 0 https://app.pulumi.com/user/aws-starter-kit/dev
prod 4 days ago 0 https://app.pulumi.com/user/aws-starter-kit/prod
test 1 hour ago 22 https://app.pulumi.com/user/aws-starter-kit/test

Nézzük meg a konfigurációs fájlokat. A Pulumi alapértelmezés szerint létrehoz egy globális Pulumi.yaml fájlt. Az ebben a fájlban tárolt információk minden stackre vonatkoznak.

name: aws-starter-kit
runtime: nodejs
description: A starter kit for AWS with basic features.

A stack konfigurációs fájlokba (például Pulumi.dev.yaml ) kerültek a stack-en belül létrehozott AWS erőforrások egyedi tulajdonságai. Itt látható egy blokk az általunk létrehozott KMS kulcshoz....

# KMS key
aws-starter-kit:kmsKey:
name: pulumi-kms-key
deletionWindowInDays: 10
description: KMS key for EKS
enableKeyRotation: false
isEnabled: true
keyUsage: ENCRYPT_DECRYPT
multiRegion: false

…valamint olyan változók, amik minden erőforrásra vonatkoznak, mint például a tag-ek.

aws:defaultTags:
tags:
project: pulumi-starter-kit
env: dev
version: "v1.0.0"

AWS erőforrások

Ha egy AWS erőforrást, például egy KMS kulcsot szeretnénk létrehozni, számos lehetőség áll rendelkezésünk, hogy a folyamat kevésbé legyen fájdalmas és időigényes. Ha az erőforrás már definiálva van, akkor használhatjuk a Pulumi Converter-t. Ez képes Pulumi kódot generálni az alábbiakból:

  1. ARM sablonok
  2. CloudFormation sablonok
  3. K8s CustomResourceDefinitions
  4. K8s YAML
  5. Terraform
Pulumi Converter

Ha már vannak meglévő erőforrásaink AWS-ben, és szeretnénk azokat a projektbe beépíteni, használhatjuk a pulumi import parancsot. Ez az erőforrásból Pulumi kódot generál bármilyen általunk választott nyelven.

Egy másik lehetőség a Pulumi AI, amely hatalmas segítség lehet, sok időt spórolhatunk meg vele, amit amúgy a dokumentációban a megfelelő oldalak keresésével töltenénk.

Pulumi AI

Itt van a KMS kulcs definiálásához létrehozott kódot. Szükségünk lesz egy erőforrásra magához a kulcshoz és egy külön erőforrásra a kulcs alias-hoz.

import * as pulumi  from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';

// Import Interfaces
import { kmsType, kmsAliasType } from '../kms-interface';

const config = new pulumi.Config();
const project = config.require("project");
const env = config.require("env");
const pulumikmsKey = config.requireObject<kmsType>("kmsKey");
const pulumikmsKeyAlias = config.requireObject<kmsAliasType>("kmsKeyAlias");

export let kmsArn:pulumi.Output<string>;

export function kms() {
const kmsKey = new aws.kms.Key(`${pulumikmsKey.name}`, {
isEnabled: pulumikmsKey.isEnabled,
keyUsage: pulumikmsKey.keyUsage,
multiRegion: pulumikmsKey.multiRegion,
deletionWindowInDays: pulumikmsKey.deletionWindowInDays,
enableKeyRotation: pulumikmsKey.enableKeyRotation,
description: pulumikmsKey.description,
tags: {
"Name" : `${env}-${pulumikmsKey.name}`,
"Env" : env,
"Project": project
},
})
kmsArn = kmsKey.arn;
kmsAlias(kmsKey);
};

function kmsAlias(kmsKey:aws.kms.Key) {
const kmsAlias = new aws.kms.Alias(`${pulumikmsKeyAlias.name}-${env}`, {
targetKeyId: kmsKey.id,
name: `${pulumikmsKeyAlias.displayName}-${env}`,
}, {dependsOn: [ kmsKey ]})
};

Létrehoztunk két interfészt is, amikkel használhatjuk a konfigurációs fájlban leírt információkat.

interface kmsType {
name: string;
deletionWindowInDays: number;
description: string;
enableKeyRotation: boolean;
isEnabled: boolean;
keyUsage: string;
multiRegion: boolean;
}

interface kmsAliasType {
name: string
displayName: string
}

export {
kmsType,
kmsAliasType
}

Helm release

A Helm release a cluster-en egy további lépést igényel a Helm Release erőforrás létrehozása mellett . Itt a teljes folyamat lépésről lépésre:

  1. EKS cluster létrehozása
const cluster = new eks.Cluster("pulumi-cluster", {});

2. A kubernetes provider használata az EKS cluster-rel való interakcióhoz

const k8sProvider = new kubernetes.Provider("k8s-provider", {
kubeconfig: cluster.kubeconfig.apply(JSON.stringify),
});

3. Egy Helm chart telepítése a clusterbe

const release = new k8s.helm.v3.Release(helmRelease.name, {
chart: helmRelease.name,
version: helmRelease.chartVersion,
namespace: helmRelease.namespace,
}, {
provider: k8sProvider,
});

A projekt felhúzása

Ha készen van áll a projektünk és szeretnénk kitelepíteni AWS-re, két opciónk van. Vagy pulumi cli segítségével csináljuk vagy írunk hozzá pipeline-t.

  • pulumi preview : ezzel a paranccsal megnézhetjük a projektben lévő erőforrásokat
  • pulumi up : az erőforrások kitelepítése a kiválasztott stackbe
$ pulumi up
Please choose a stack, or create a new one: dev
Previewing update (dev)

Type Name Plan
+ pulumi:pulumi:Stack aws-starter-kit-dev create
+ ├─ eks:index:Cluster pulumi-cluster create
+ │ ├─ eks:index:ServiceRole pulumi-cluster-instanceRole create
+ │ │ ├─ aws:iam:Role pulumi-cluster-instanceRole-role create
+ │ │ ├─ aws:iam:RolePolicyAttachment pulumi-cluster-instanceRole-3eb088f2 create
+ │ │ ├─ aws:iam:RolePolicyAttachment pulumi-cluster-instanceRole-03516f97 create
+ │ │ └─ aws:iam:RolePolicyAttachment pulumi-cluster-instanceRole-e1b295bd create
+ │ ├─ eks:index:ServiceRole pulumi-cluster-eksRole create
+ │ │ ├─ aws:iam:Role pulumi-cluster-eksRole-role create
+ │ │ └─ aws:iam:RolePolicyAttachment pulumi-cluster-eksRole-4b490823 create
+ │ ├─ aws:ec2:SecurityGroup pulumi-cluster-eksClusterSecurityGroup create
+ │ ├─ aws:ec2:SecurityGroupRule pulumi-cluster-eksClusterInternetEgressRule create
+ │ ├─ aws:eks:Cluster pulumi-cluster-eksCluster create
+ │ ├─ pulumi:providers:kubernetes pulumi-cluster-eks-k8s create
+ │ ├─ pulumi:providers:kubernetes pulumi-cluster-provider create
+ │ ├─ aws:ec2:SecurityGroup pulumi-cluster-nodeSecurityGroup create
+ │ ├─ kubernetes:core/v1:ConfigMap pulumi-cluster-nodeAccess create
+ │ ├─ aws:iam:OpenIdConnectProvider pulumi-cluster-oidcProvider create
+ │ ├─ eks:index:VpcCni pulumi-cluster-vpc-cni create
+ │ ├─ aws:ec2:SecurityGroupRule pulumi-cluster-eksNodeIngressRule create
+ │ ├─ aws:ec2:SecurityGroupRule pulumi-cluster-eksExtApiServerClusterIngressRule create
+ │ ├─ aws:ec2:SecurityGroupRule pulumi-cluster-eksNodeClusterIngressRule create
+ │ ├─ aws:ec2:SecurityGroupRule pulumi-cluster-eksClusterIngressRule create
+ │ └─ aws:ec2:SecurityGroupRule pulumi-cluster-eksNodeInternetEgressRule create
+ ├─ aws:ecr:Repository pulumi-ecr2 create
+ ├─ aws:kms:Key pulumi-kms-key-dev create
+ ├─ aws:ecr:Repository pulumi-ecr1 create
+ ├─ aws:s3:Bucket pulumi-bucket2 create
+ ├─ aws:iam:Policy cloudwatch-irsa-policy create
+ ├─ aws:ec2:Vpc pulumi-vpc create
+ ├─ aws:ec2:Eip pulumi-elastic-ip create
+ ├─ aws:s3:Bucket pulumi-bucket1 create

A Pulumi útmutatókat és erőforrásokat is biztosít CICD témában. Itt van például egy Pulumi által adott Github Workflow:

name: Pulumi
on:
- pull_request
jobs:
preview:
name: Preview
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3.5.0
with:
node-version-file: package.json
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-region: ${{ secrets.AWS_REGION }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- run: npm install
- uses: pulumi/actions@v3
with:
command: preview
stack-name: org-name/stack-name
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}

Összegzés

A felhőalapú megoldások mellett az Infrastructure as Code (IaC) technológiák is gyorsan fejlődnek, rugalmasságot és hatékonyságot kínálva az infrastruktúra egyedi kezelésében.

Ha felhőmegoldásokban jártas partnert keresel, akár erőforrásaidat költöztetnéd a felhőbe, vagy egy már meglévő felhőkörnyezetet szeretnél optimalizálni, keress minket bátran:

--

--