Created
December 3, 2019 20:23
-
-
Save leepa/515bfabc1beca3b9b717c6dcbc2686c4 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 cdk = require('@aws-cdk/core'); | |
| import autoscaling = require('@aws-cdk/aws-autoscaling'); | |
| import ec2 = require('@aws-cdk/aws-ec2'); | |
| import eks = require('@aws-cdk/aws-eks'); | |
| import iam = require('@aws-cdk/aws-iam'); | |
| import fs = require('fs'); | |
| import path = require('path'); | |
| import { safeLoadAll, safeLoad } from 'js-yaml'; | |
| export class ProductionCluster extends eks.Cluster { | |
| protected autoscalingGroups: autoscaling.AutoScalingGroup[] = []; | |
| constructor(scope: cdk.Construct, id: string, props: eks.ClusterProps) { | |
| super(scope, id, props); | |
| } | |
| /** | |
| * Wrap addCapacity from eks.Cluster to provide a tracking of the capacity | |
| * we have added. | |
| * | |
| * @param id | |
| * @param options | |
| */ | |
| public addCapacity(id: string, options: eks.CapacityOptions): autoscaling.AutoScalingGroup { | |
| const asg = super.addCapacity(id, options); | |
| this.autoscalingGroups.push(asg); | |
| return asg; | |
| } | |
| /** | |
| * Wrap addAutoScalingGroup to provide a tracking of ASGs added. | |
| * | |
| * @param autoScalingGroup | |
| * @param options | |
| */ | |
| public addAutoScalingGroup(autoScalingGroup: autoscaling.AutoScalingGroup, options: eks.AutoScalingGroupOptions) { | |
| this.autoscalingGroups.push(autoScalingGroup); | |
| super.addAutoScalingGroup(autoScalingGroup, options); | |
| } | |
| public addDashboard() { | |
| const f = fs.readFileSync(path.resolve(__dirname, 'k8s', 'kubernetes-dashboard.yaml')); | |
| const resources = safeLoadAll(f.toString()); | |
| this.addResource('Dashboard', ...resources); | |
| } | |
| public addAlbIngressController(): eks.KubernetesResource { | |
| const rbac_file = fs.readFileSync(path.resolve(__dirname, 'k8s', 'alb-rbac-role.yaml')); | |
| const rbac = safeLoadAll(rbac_file.toString()); | |
| const f = fs.readFileSync(path.resolve(__dirname, 'k8s', 'alb-ingress-controller.yaml')); | |
| let resources = safeLoadAll(f.toString()); | |
| const role = this.addResource('AlbRbacRole', ...rbac); | |
| resources[0]['spec']['template']['spec']['containers'][0]['args'].push('--cluster-name=' + this.clusterName); | |
| const alb = this.addResource('AlbIngressController', ...resources) | |
| alb.node.addDependency(role); | |
| return alb; | |
| } | |
| public deploy2048(): eks.KubernetesResource { | |
| const ns = this.addResource('TwentyFortyEightNS', | |
| { | |
| "apiVersion": "v1", | |
| "kind": "Namespace", | |
| "metadata": { | |
| "name": "2048-game" | |
| } | |
| } | |
| ); | |
| const files = [ | |
| '2048-deployment.yaml', | |
| '2048-service.yaml', | |
| '2048-ingress.yaml', | |
| ] | |
| const resources = files.map(rf => { | |
| const f = fs.readFileSync(path.resolve(__dirname, 'k8s', '2048', rf)); | |
| return safeLoad(f.toString()); | |
| }); | |
| const r = this.addResource('TwentyFortyEight', ...resources); | |
| r.node.addDependency(ns); | |
| return r; | |
| } | |
| public addAlbPermissionsToAllCapacity() { | |
| this.autoscalingGroups.forEach(asg => { | |
| const role = asg.role; | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "acm:DescribeCertificate", | |
| "acm:ListCertificates", | |
| "acm:GetCertificate" | |
| ] | |
| })); | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "ec2:AuthorizeSecurityGroupIngress", | |
| "ec2:CreateSecurityGroup", | |
| "ec2:CreateTags", | |
| "ec2:DeleteTags", | |
| "ec2:DeleteSecurityGroup", | |
| "ec2:DescribeAccountAttributes", | |
| "ec2:DescribeAddresses", | |
| "ec2:DescribeInstances", | |
| "ec2:DescribeInstanceStatus", | |
| "ec2:DescribeInternetGateways", | |
| "ec2:DescribeNetworkInterfaces", | |
| "ec2:DescribeSecurityGroups", | |
| "ec2:DescribeSubnets", | |
| "ec2:DescribeTags", | |
| "ec2:DescribeVpcs", | |
| "ec2:ModifyInstanceAttribute", | |
| "ec2:ModifyNetworkInterfaceAttribute", | |
| "ec2:RevokeSecurityGroupIngress", | |
| ] | |
| })); | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "elasticloadbalancing:AddListenerCertificates", | |
| "elasticloadbalancing:AddTags", | |
| "elasticloadbalancing:CreateListener", | |
| "elasticloadbalancing:CreateLoadBalancer", | |
| "elasticloadbalancing:CreateRule", | |
| "elasticloadbalancing:CreateTargetGroup", | |
| "elasticloadbalancing:DeleteListener", | |
| "elasticloadbalancing:DeleteLoadBalancer", | |
| "elasticloadbalancing:DeleteRule", | |
| "elasticloadbalancing:DeleteTargetGroup", | |
| "elasticloadbalancing:DeregisterTargets", | |
| "elasticloadbalancing:DescribeListenerCertificates", | |
| "elasticloadbalancing:DescribeListeners", | |
| "elasticloadbalancing:DescribeLoadBalancers", | |
| "elasticloadbalancing:DescribeLoadBalancerAttributes", | |
| "elasticloadbalancing:DescribeRules", | |
| "elasticloadbalancing:DescribeSSLPolicies", | |
| "elasticloadbalancing:DescribeTags", | |
| "elasticloadbalancing:DescribeTargetGroups", | |
| "elasticloadbalancing:DescribeTargetGroupAttributes", | |
| "elasticloadbalancing:DescribeTargetHealth", | |
| "elasticloadbalancing:ModifyListener", | |
| "elasticloadbalancing:ModifyLoadBalancerAttributes", | |
| "elasticloadbalancing:ModifyRule", | |
| "elasticloadbalancing:ModifyTargetGroup", | |
| "elasticloadbalancing:ModifyTargetGroupAttributes", | |
| "elasticloadbalancing:RegisterTargets", | |
| "elasticloadbalancing:RemoveListenerCertificates", | |
| "elasticloadbalancing:RemoveTags", | |
| "elasticloadbalancing:SetIpAddressType", | |
| "elasticloadbalancing:SetSecurityGroups", | |
| "elasticloadbalancing:SetSubnets", | |
| "elasticloadbalancing:SetWebACL" | |
| ] | |
| })); | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "iam:CreateServiceLinkedRole", | |
| "iam:GetServerCertificate", | |
| "iam:ListServerCertificates" | |
| ] | |
| })); | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "waf-regional:GetWebACLForResource", | |
| "waf-regional:GetWebACL", | |
| "waf-regional:AssociateWebACL", | |
| "waf-regional:DisassociateWebACL" | |
| ] | |
| })); | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "tag:GetResources", | |
| "tag:TagResources" | |
| ] | |
| })); | |
| role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "waf:GetWebACL" | |
| ] | |
| })); | |
| }); | |
| } | |
| public addCAToScalingGroup(asg: autoscaling.AutoScalingGroup) { | |
| asg.role.addToPolicy(new iam.PolicyStatement({ | |
| resources: ['*'], | |
| actions: [ | |
| "autoscaling:DescribeAutoScalingGroups", | |
| "autoscaling:DescribeAutoScalingInstances", | |
| "autoscaling:SetDesiredCapacity", | |
| "autoscaling:TerminateInstanceInAutoScalingGroup", | |
| "autoscaling:DescribeTags" | |
| ] | |
| })); | |
| this.addResource("ClusterAutoScaler", { | |
| "apiVersion": "v1", | |
| "kind": "ServiceAccount", | |
| "metadata": { | |
| "labels": { | |
| "k8s-addon": "cluster-autoscaler.addons.k8s.io", | |
| "k8s-app": "cluster-autoscaler" | |
| }, | |
| "name": "cluster-autoscaler", | |
| "namespace": "kube-system" | |
| } | |
| }, | |
| { | |
| "apiVersion": "rbac.authorization.k8s.io/v1beta1", | |
| "kind": "ClusterRole", | |
| "metadata": { | |
| "name": "cluster-autoscaler", | |
| "labels": { | |
| "k8s-addon": "cluster-autoscaler.addons.k8s.io", | |
| "k8s-app": "cluster-autoscaler" | |
| } | |
| }, | |
| "rules": [ | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "events", | |
| "endpoints" | |
| ], | |
| "verbs": [ | |
| "create", | |
| "patch" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "pods/eviction" | |
| ], | |
| "verbs": [ | |
| "create" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "pods/status" | |
| ], | |
| "verbs": [ | |
| "update" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "endpoints" | |
| ], | |
| "resourceNames": [ | |
| "cluster-autoscaler" | |
| ], | |
| "verbs": [ | |
| "get", | |
| "update" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "nodes" | |
| ], | |
| "verbs": [ | |
| "watch", | |
| "list", | |
| "get", | |
| "update" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "pods", | |
| "services", | |
| "replicationcontrollers", | |
| "persistentvolumeclaims", | |
| "persistentvolumes" | |
| ], | |
| "verbs": [ | |
| "watch", | |
| "list", | |
| "get" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "extensions" | |
| ], | |
| "resources": [ | |
| "replicasets", | |
| "daemonsets" | |
| ], | |
| "verbs": [ | |
| "watch", | |
| "list", | |
| "get" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "policy" | |
| ], | |
| "resources": [ | |
| "poddisruptionbudgets" | |
| ], | |
| "verbs": [ | |
| "watch", | |
| "list" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "apps" | |
| ], | |
| "resources": [ | |
| "statefulsets", | |
| "replicasets" | |
| ], | |
| "verbs": [ | |
| "watch", | |
| "list", | |
| "get" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "storage.k8s.io" | |
| ], | |
| "resources": [ | |
| "storageclasses" | |
| ], | |
| "verbs": [ | |
| "watch", | |
| "list", | |
| "get" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "apiVersion": "rbac.authorization.k8s.io/v1beta1", | |
| "kind": "Role", | |
| "metadata": { | |
| "name": "cluster-autoscaler", | |
| "namespace": "kube-system", | |
| "labels": { | |
| "k8s-addon": "cluster-autoscaler.addons.k8s.io", | |
| "k8s-app": "cluster-autoscaler" | |
| } | |
| }, | |
| "rules": [ | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "configmaps" | |
| ], | |
| "verbs": [ | |
| "create" | |
| ] | |
| }, | |
| { | |
| "apiGroups": [ | |
| "" | |
| ], | |
| "resources": [ | |
| "configmaps" | |
| ], | |
| "resourceNames": [ | |
| "cluster-autoscaler-status" | |
| ], | |
| "verbs": [ | |
| "delete", | |
| "get", | |
| "update" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "apiVersion": "rbac.authorization.k8s.io/v1beta1", | |
| "kind": "ClusterRoleBinding", | |
| "metadata": { | |
| "name": "cluster-autoscaler", | |
| "labels": { | |
| "k8s-addon": "cluster-autoscaler.addons.k8s.io", | |
| "k8s-app": "cluster-autoscaler" | |
| } | |
| }, | |
| "roleRef": { | |
| "apiGroup": "rbac.authorization.k8s.io", | |
| "kind": "ClusterRole", | |
| "name": "cluster-autoscaler" | |
| }, | |
| "subjects": [ | |
| { | |
| "kind": "ServiceAccount", | |
| "name": "cluster-autoscaler", | |
| "namespace": "kube-system" | |
| } | |
| ] | |
| }, | |
| { | |
| "apiVersion": "rbac.authorization.k8s.io/v1beta1", | |
| "kind": "RoleBinding", | |
| "metadata": { | |
| "name": "cluster-autoscaler", | |
| "namespace": "kube-system", | |
| "labels": { | |
| "k8s-addon": "cluster-autoscaler.addons.k8s.io", | |
| "k8s-app": "cluster-autoscaler" | |
| } | |
| }, | |
| "roleRef": { | |
| "apiGroup": "rbac.authorization.k8s.io", | |
| "kind": "Role", | |
| "name": "cluster-autoscaler" | |
| }, | |
| "subjects": [ | |
| { | |
| "kind": "ServiceAccount", | |
| "name": "cluster-autoscaler", | |
| "namespace": "kube-system" | |
| } | |
| ] | |
| }, | |
| { | |
| "apiVersion": "apps/v1", | |
| "kind": "Deployment", | |
| "metadata": { | |
| "name": "cluster-autoscaler", | |
| "namespace": "kube-system", | |
| "labels": { | |
| "app": "cluster-autoscaler" | |
| } | |
| }, | |
| "spec": { | |
| "replicas": 1, | |
| "selector": { | |
| "matchLabels": { | |
| "app": "cluster-autoscaler" | |
| } | |
| }, | |
| "template": { | |
| "metadata": { | |
| "labels": { | |
| "app": "cluster-autoscaler" | |
| } | |
| }, | |
| "spec": { | |
| "serviceAccountName": "cluster-autoscaler", | |
| "containers": [ | |
| { | |
| "image": "k8s.gcr.io/cluster-autoscaler:v1.12.3", | |
| "name": "cluster-autoscaler", | |
| "resources": { | |
| "limits": { | |
| "cpu": "100m", | |
| "memory": "300Mi" | |
| }, | |
| "requests": { | |
| "cpu": "100m", | |
| "memory": "300Mi" | |
| } | |
| }, | |
| "command": [ | |
| "./cluster-autoscaler", | |
| "--v=4", | |
| "--stderrthreshold=info", | |
| "--cloud-provider=aws", | |
| "--skip-nodes-with-local-storage=false", | |
| "--nodes=3:8:" + asg.autoScalingGroupName | |
| ], | |
| "env": [ | |
| { | |
| "name": "AWS_REGION", | |
| "value": cdk.Aws.REGION, | |
| } | |
| ], | |
| "volumeMounts": [ | |
| { | |
| "name": "ssl-certs", | |
| "mountPath": "/etc/ssl/certs/ca-certificates.crt", | |
| "readOnly": true | |
| } | |
| ], | |
| "imagePullPolicy": "Always" | |
| } | |
| ], | |
| "volumes": [ | |
| { | |
| "name": "ssl-certs", | |
| "hostPath": { | |
| "path": "/etc/ssl/certs/ca-bundle.crt" | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can you also post the app stack code?