From 507a660248df0fe90fe39e91f70c4139a308751e Mon Sep 17 00:00:00 2001 From: Martin Linkhorst Date: Tue, 23 Jan 2018 18:22:29 +0100 Subject: [PATCH] docs: add readme with tutorial and manifests --- LICENSE | 2 +- README.md | 228 +++++++++++++++++- docs/img/stack-create.png | Bin 0 -> 23933 bytes docs/img/stack-delete.png | Bin 0 -> 16105 bytes docs/img/stack-update.png | Bin 0 -> 16667 bytes manifests/cfs-my-bucket-v1.yaml | 15 ++ manifests/cfs-my-bucket-v2.yaml | 15 ++ manifests/cfs-my-bucket-v3.yaml | 22 ++ ...s-my-bucket.yaml => cfs-my-bucket-v4.yaml} | 5 +- 9 files changed, 282 insertions(+), 5 deletions(-) create mode 100644 docs/img/stack-create.png create mode 100644 docs/img/stack-delete.png create mode 100644 docs/img/stack-update.png create mode 100644 manifests/cfs-my-bucket-v1.yaml create mode 100644 manifests/cfs-my-bucket-v2.yaml create mode 100644 manifests/cfs-my-bucket-v3.yaml rename manifests/{cfs-my-bucket.yaml => cfs-my-bucket-v4.yaml} (75%) diff --git a/LICENSE b/LICENSE index 664434c..ab27bb3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Martin Linkhorst +Copyright (c) 2018 Martin Linkhorst Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index fcd4b1c..ac70104 100644 --- a/README.md +++ b/README.md @@ -1 +1,227 @@ -# cloudformation-operator \ No newline at end of file +# cloudformation-operator + +A Kubernetes operator for managing CloudFormation stacks via `kubectl` and a custom resource definition. + +**Warning: this project is in alpha state. It should only be used to try out the demo and get the general idea.** + +# Setup + +You need full API access to a cluster running at least Kubernetes v1.7. + +For simplicity, start the CloudFormation operator locally. This would run as a Pod in your cluster later. + +```console +$ go run main.go --interval=10s --region=eu-central-1 +``` + +Modify the region flag to match yours and make sure you have permission to create and delete CloudFormation stacks. + +The operator should print some output but shouldn't actually do anything at this point. Leave in running and continue the following steps in a separate terminal window. + +# Demo + +Create a new custom resource called `Stack` by submitting `manifests/crd-cloudformation-stack.yaml` to your cluster. + +```console +$ kubectl apply -f manifests/crd-cloudformation-stack.yaml +customresourcedefinition "stacks.cloudformation.linki.space" created +``` + +This will add another resource to your cluster that feels much like a native Kubernetes resource. + +```console +$ kubectl get stacks +No resources found. +``` + +Currently you don't have any stacks. Let's create a simple one that manages an S3 bucket: + +```yaml +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Suspended +``` + +The Stack resource's definition looks a lot like any other Kubernetes resource manifest. +The `spec` section describes an attribute called `template` which contains a regular CloudFormation template. + +Go ahead and submit the stack definition to your cluster: + +```console +$ kubectl apply -f manifests/cfs-my-bucket-v1.yaml +stack "my-bucket" created +$ kubectl get stacks +NAME AGE +my-bucket 21s +``` + +Open your AWS CloudFormation console and find your new stack. + +![Create stack](docs/img/stack-create.png) + +Once the CloudFormation stack is created check that your S3 bucket was created as well. + +The operator will write back additional information about the CloudFormation Stack to your Kubernetes resource's `status` section, e.g. the `stackID`: + +```console +$ kubectl get stacks my-bucket -o yaml +spec: + template: + ... +status: + stackID: arn:aws:cloudformation:eu-central-1:123456789012:stack/my-bucket/327b7d3c-f27b-4b94-8d17-92a1d9da85ab +``` + +VoilĂ , you just created a CloudFormation stack by only talking to Kubernetes. + +You can also update your stack: Let's change the `VersioningConfiguration` from `Suspended` to `Enabled`: + +```yaml +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Enabled +``` + +As with most Kubernetes resources you can update your `Stack` resource by applying a changed manifest to your Kubernetes cluster or by using `kubectl edit stack my-stack`. + +```console +$ kubectl apply -f manifests/cfs-my-bucket-v2.yaml +stack "my-bucket" configured +``` + +Wait until the operator discovered and executed the change, then look at your AWS CloudFormation console again and find your stack being updated, yay. + +![Update stack](docs/img/stack-update.png) + +However, often you'll want to extract dynamic values out of your CloudFormation stack template into so called `Parameters` so that your template itself doesn't change that often and, well, is really a *template*. + +Let's extract the `VersioningConfiguration` into a parameter: + +```yaml +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + parameters: + VersioningConfiguration: Enabled + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Parameters: + VersioningConfiguration: + Type: String + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: + Ref: VersioningConfiguration +``` + +and apply it to your cluster: + +```console +$ kubectl apply -f manifests/cfs-my-bucket-v3.yaml +stack "my-bucket" configured +``` + +Since we changed the template a little this will update your CloudFormation stack. However, since we didn't actually change anything because we injected the same `VersioningConfiguration` value as before, your S3 bucket shouldn't change. + +As you can any CloudFormation parameters defined in the CloudFormation template can be specified in the `Stack` resource's `spec.parameters` section. It's a simple key/value map. + +Furthermore, CloudFormation supports so called `Outputs`. These can be used for dynamic values that are only known after a stack has been created. +In our example, we don't define a particular S3 bucket name but instead let AWS generate one for us. + +Let's change our CloudFormation template to expose the generated bucket name via an `Output`: + +```yaml +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + parameters: + VersioningConfiguration: Enabled + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Parameters: + VersioningConfiguration: + Type: String + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: + Ref: VersioningConfiguration + + Outputs: + BucketName: + Value: !Ref 'S3Bucket' +``` + +Apply the change to our cluster and wait until the operator has successfully updated the CloudFormation stack. + +```console +$ kubectl apply -f manifests/cfs-my-bucket-v4.yaml +stack "my-bucket" configured +``` + +Every `Output` you define will be available in your Kubernetes resource's `status` section under the `outputs` field as a key/value map. + +Let's check the name of our S3 bucket: + +```console +$ kubectl get stacks my-bucket -o yaml +spec: + template: + ... +status: + stackID: ... + outputs: + BucketName: my-bucket-s3bucket-tarusnslfnsj +``` + +In the template we defined an `Output` called `BucketName` that should contain the name of our bucket after stack creation. Looking up the corresponding value under `.status.outputs[BucketName]` reveals that our bucket was named `my-bucket-s3bucket-tarusnslfnsj`. + +The operator captures the whole lifecycle of a CloudFormation stack. So if you delete the resource from Kubernetes, the operator will teardown the CloudFormation stack as well. Let's do that now: + +```console +$ kubectl delete stack my-bucket +stack "my-bucket" deleted +``` + +Check your CloudFormation console once more and validate that your stack as well as your S3 bucket were deleted. + +![Delete stack](docs/img/stack-delete.png) diff --git a/docs/img/stack-create.png b/docs/img/stack-create.png new file mode 100644 index 0000000000000000000000000000000000000000..1ec17517478d4301794d1ee103a23de4e8ef66d4 GIT binary patch literal 23933 zcmZUbV|b;@(y(JYnP_6$wrx8TCllMYZQHhOn-kkMzU=d!ee|s#>+0v}>guk>>aM%` zTA^|>qOeeyPyhe`u;OAu3IG7WXy0jT2(a((tX6JV005{OGeJQ)aX~>mIXi1(GYcaC z0I|@-Byc4~Gt}Ykr@5aXNCL4)Zpa15d~UEg_Y@TPfJhP$zCHvL6#j&4s7gXLFvoH~ zu%PksLqha_qEM}X8_LNI^#Y+P9Rf2ts#(^4gK8_a6cW}+ z)CC=YE43ey6o}6)dOuZtL#O~gHL4~xh7^I|+_wffd3pywBl@~;VWGi{C#r^jgZDxF zU2~evOcst*eyo0)fv_VOPcWfR{lnX8_)Fz?nBgUkhFHvte)cazBRqGN_>4nRBfX6| zA9mDh<5QCq+8fAp1FInSd#pP)94~t+aX9--gD96z4So_%hp0ib-nq}dgu>6c&l?N! zVH20230uFOaPDFD_n8p(DWm|}%)N+xgzgtiXEPlt$Rsxz1b6XldS-*opUI5g)lyz1 z(;dNLrMNmB!Np9pF!4*_41Wr^g~@&IJ{3C(Um_|HP8w53pjn2+v9@|%czowR0C9Sd zp9yhEAV5%ikWzpteOksMbeTV7fS;IVf7jy0W{)}u%Sdy@Q}3tI7;2=X)&r#Q_}6>i zw7)T$KisW-MiKB0xNt1|+` zCIfcNfrasb+?@tv13(+7rG)^<#e=E<(CPs%<%6l?r&$4j;zL{keDqVXeF2hbG64caqEo(`j^|91^e2ZV8NRShl{ z6m2l_jsqL`RB&@|p$)MIij^O2&+<;Y4evV?jwm1sk>iSjp zH}AOL&|b%bQ1B=Jl7+y#hA4+zhZKdV3`h^a?<10rDv@;{3POqx`596;0JclKYp~0S z6j~r$M+h1VQoyA^e!_MFW#)4qN+rue&>n9vf^^Gb$K0Cv?(-fckb5kzMK+rtHO3-A zeL!$Pevl6%J){&w-5;+`t4K3XG*5Y_k%U)Hc}CGLz#`ft^jL5%y(&-PTPEsQY*%tt zawHn$eNfQOqUFqx)I&F8soe8CE21UuOOJbe7;o*vW{lrqpJP#Nj~>Imf(gDeQge^N}(!X)F@hJlBQlA?oh zgz84#O3q68GryT{T)0AqLasvooOa>#n3R$1f#E^s*yNb3(hP+N1wX|q1-LRzX#`CU zt&Libwp`2hfM0M~OHK z1>L1Y1x-R_s$@E+1hxHWB$KP#RhuQB{Ij}r0yd31jXU)`i9MUVqP#jk4S>UZ>-pRG z3wyBzEAYqZRvi-ySKInu%OfizSBiR#2ULbxmYljRal@ye3@wecYx`GP zS1X%2&7Vd$hj`{c13t3hNZ>}{9O3%IAJB$rdFotd`1{}g1UuR3V)aO(8 zv`*e9gx3R)6b^3t7H618A4<;5Ss7Vt*Ug&YFCQ<>|EzP%;cVgr;{3_F&C<&<%98DD z=s@Z`?HuZ;>|Azfe*5L|?&0)$U%R-XzdAxS=`)ea-@)YuZB}t}Q4lWML_s zBD>go;d{D7Y$Pb8Fr*wLml9YzoOhDX`9RM6soTvRm;yB#+3dMtm6Kj2a9lBQ^Gd`gkug3^4}@%2^Ne zoLq1F6s^jA%B(6sD>v(2g`-rbWX)&HTg*A^nC)5j;VK-pHEZEC(3-0ZIv-!(9|T=D zU73G|{ETCLZ=1C+xEXp%CtztjEI&9pfcHB3(Dw9|@@>hnuJ1n-+{*7p^VsSfv>WfD z-hy%sTn?KElL+gwII!w`^nZabr$;8txv) zfqlhB>_TofcbXT`|=ZvWE6d#?`d z1s*s2o4#MeV^N}LgtVI{FsJ8T`_3n0M%CkJ?ON?qy0#s5k7XZ=jLT}vY1Qjm)@^#8 zd-v5#-C37SCsu7{?)3*re=3)<2DvRer#jKB+&8*Bf<2F3{}ejAUk3hZ-$I*T_Re

MG0k8ss`4tOotFFl7xmxhRqZx;|1=`| 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

C3Az)e# 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 KE?X{b9PnR#{}vhm literal 0 HcmV?d00001 diff --git a/docs/img/stack-delete.png b/docs/img/stack-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..d4031c4ef66cdd715fe2314cf5b7df6f1632d035 GIT binary patch literal 16105 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 literal 0 HcmV?d00001 diff --git a/docs/img/stack-update.png b/docs/img/stack-update.png new file mode 100644 index 0000000000000000000000000000000000000000..ffbe33c4c0ce789491b10269220c7188b0827d90 GIT binary patch literal 16667 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 literal 0 HcmV?d00001 diff --git a/manifests/cfs-my-bucket-v1.yaml b/manifests/cfs-my-bucket-v1.yaml new file mode 100644 index 0000000..781f9ef --- /dev/null +++ b/manifests/cfs-my-bucket-v1.yaml @@ -0,0 +1,15 @@ +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Suspended diff --git a/manifests/cfs-my-bucket-v2.yaml b/manifests/cfs-my-bucket-v2.yaml new file mode 100644 index 0000000..8a969b0 --- /dev/null +++ b/manifests/cfs-my-bucket-v2.yaml @@ -0,0 +1,15 @@ +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Enabled diff --git a/manifests/cfs-my-bucket-v3.yaml b/manifests/cfs-my-bucket-v3.yaml new file mode 100644 index 0000000..9ec930a --- /dev/null +++ b/manifests/cfs-my-bucket-v3.yaml @@ -0,0 +1,22 @@ +apiVersion: cloudformation.linki.space/v1alpha1 +kind: Stack +metadata: + name: my-bucket +spec: + parameters: + VersioningConfiguration: Enabled + template: | + --- + AWSTemplateFormatVersion: '2010-09-09' + + Parameters: + VersioningConfiguration: + Type: String + + Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: + Ref: VersioningConfiguration diff --git a/manifests/cfs-my-bucket.yaml b/manifests/cfs-my-bucket-v4.yaml similarity index 75% rename from manifests/cfs-my-bucket.yaml rename to manifests/cfs-my-bucket-v4.yaml index 33a94cf..ea48925 100644 --- a/manifests/cfs-my-bucket.yaml +++ b/manifests/cfs-my-bucket-v4.yaml @@ -4,7 +4,7 @@ metadata: name: my-bucket spec: parameters: - VersioningConfiguration: Suspended + VersioningConfiguration: Enabled template: | --- AWSTemplateFormatVersion: '2010-09-09' @@ -17,7 +17,6 @@ spec: S3Bucket: Type: AWS::S3::Bucket Properties: - AccessControl: Private VersioningConfiguration: Status: Ref: VersioningConfiguration @@ -25,4 +24,4 @@ spec: Outputs: BucketName: Value: !Ref 'S3Bucket' - Description: Name of the sample Amazon S3 bucket with a lifecycle configuration. + Description: Name of the sample Amazon S3 bucket.