Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
import * as aws from "@pulumi/aws";
import { asset } from "@pulumi/pulumi";
let region = aws.config.requireRegion();
///////////////////
// Lambda Function
///////////////////
let policy = {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com",
},
"Effect": "Allow",
"Sid": "",
},
],
{
bucket: `${config.targetDomain}-logs`,
acl: "private",
});
const tenMinutes = 60 * 10;
let certificateArn: pulumi.Input = config.certificateArn!;
/**
* Only provision a certificate (and related resources) if a certificateArn is _not_ provided via configuration.
*/
if (config.certificateArn === undefined) {
const eastRegion = new aws.Provider("east", {
profile: aws.config.profile,
region: "us-east-1", // Per AWS, ACM certificate must be in the us-east-1 region.
});
const certificate = new aws.acm.Certificate("certificate", {
domainName: config.targetDomain,
validationMethod: "DNS",
}, { provider: eastRegion });
const domainParts = getDomainAndSubdomain(config.targetDomain);
const hostedZoneId = aws.route53.getZone({ name: domainParts.parentDomain }, { async: true }).then(zone => zone.zoneId);
/**
* Create a DNS record to prove that we _own_ the domain we're requesting a certificate for.
* See https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate-dns.html for more info.
*/
const certificateValidationDomain = new aws.route53.Record(`${config.targetDomain}-validation`, {
version: "1.14",
tags: {
"Project": "k8s-aws-cluster",
"Org": "pulumi",
},
clusterSecurityGroupTags: { "ClusterSecurityGroupTag": "true" },
nodeSecurityGroupTags: { "NodeSecurityGroupTag": "true" },
enabledClusterLogTypes: ["api", "audit", "authenticator", "controllerManager", "scheduler"],
// endpointPublicAccess: false, // Requires bastion to access cluster API endpoint
// endpointPrivateAccess: true, // Requires bastion to access cluster API endpoint
});
// Export the cluster details.
export const kubeconfig = cluster.kubeconfig.apply(JSON.stringify);
export const clusterName = cluster.core.cluster.name;
export const region = aws.config.region;
export const securityGroupIds = [cluster.nodeSecurityGroup.id];
// Create a Standard node group of t2.medium workers.
const ngStandard = new eks.NodeGroup(`${projectName}-ng-standard`, {
cluster: cluster,
instanceProfile: new aws.iam.InstanceProfile("ng-standard", {role: stdNodegroupIamRoleName}),
nodeAssociatePublicIpAddress: false,
nodeSecurityGroup: cluster.nodeSecurityGroup,
clusterIngressRule: cluster.eksClusterIngressRule,
amiId: "ami-0ca5998dc2c88e64b", // k8s v1.14.7 in us-west-2
instanceType: "t2.medium",
desiredCapacity: 3,
minSize: 3,
maxSize: 10,
labels: {"amiId": "ami-0ca5998dc2c88e64b"},
cloudFormationTags: clusterName.apply(clusterName => ({
}, { parent: privateSubnet }));
new aws.ec2.Route(`${name}-route-private-sn-to-nat-${index + 1}`, {
routeTableId: this.privateRouteTables[index].id,
destinationCidrBlock: "0.0.0.0/0",
natGatewayId: this.natGateways[index].id,
}, { parent: this.privateRouteTables[index] });
new aws.ec2.RouteTableAssociation(`${name}-private-rta-${index + 1}`, {
subnetId: privateSubnet.id,
routeTableId: this.privateRouteTables[index].id,
}, { parent: this.privateRouteTables[index] });
}
// Create gateway endpoints if necessary
if (args.endpoints.s3) {
new aws.ec2.VpcEndpoint(`${name}-s3-endpoint`, {
vpcId: this.vpc.id,
serviceName: `com.amazonaws.${aws.config.region}.s3`,
routeTableIds: [this.publicRouteTable.id, ...this.privateRouteTables.map(x => x.id)],
}, { parent: this.vpc });
}
if (args.endpoints.dynamodb) {
new aws.ec2.VpcEndpoint(`${name}-dynamodb-endpoint`, {
vpcId: this.vpc.id,
serviceName: `com.amazonaws.${aws.config.region}.dynamodb`,
routeTableIds: [this.publicRouteTable.id, ...this.privateRouteTables.map(x => x.id)],
}, { parent: this.vpc });
}
this.registerOutputs({});
}
enableFlowLoggingToCloudWatchLogs(trafficType) {
// Deploy fluentd using the Helm chart.
const provider = new k8s.Provider("provider", {kubeconfig: config.kubeconfig});
const fluentdCloudWatchLogGroup = new aws.cloudwatch.LogGroup(name);
export let fluentdCloudWatchLogGroupName = fluentdCloudWatchLogGroup.name;
const fluentdCloudwatch = new k8s.helm.v2.Chart(name,
{
namespace: config.clusterSvcsNamespaceName,
chart: "fluentd-cloudwatch",
version: "0.11.0",
fetchOpts: {
repo: "https://kubernetes-charts-incubator.storage.googleapis.com/",
},
values: {
extraVars: [ "{ name: FLUENT_UID, value: '0' }" ],
rbac: {create: true},
awsRegion: aws.config.region,
logGroupName: fluentdCloudWatchLogGroup.name,
},
transformations: [
(obj: any) => {
// Do transformations on the YAML to set the namespace
if (obj.metadata) {
obj.metadata.namespace = config.clusterSvcsNamespaceName;
}
},
],
},
{providers: { kubernetes: provider }},
);
cb(null, {});
} catch (err) {
cb(err);
}
},
{ parent: this },
);
this.lambda = collector.lambda;
// Although Lambda will create this on-demand, we create the log group explicitly so that we can delete it when
// the stack gets torn down.
const logGroup = new aws.cloudwatch.LogGroup(name, {
name: this.lambda.name.apply(n => "/aws/lambda/" + n),
}, { parent: this });
const region = aws.config.requireRegion();
const permission = new aws.lambda.Permission(name, {
action: "lambda:invokeFunction",
function: this.lambda,
principal: "logs." + region + ".amazonaws.com",
}, { parent: this });
}
}
async (ev: LogsPayload, ctx: aws.serverless.Context, cb: (error: any, result?: {}) => void) => {
try {
const zlib = await import("zlib");
const payload = new Buffer(ev.awslogs.data, "base64");
const result = zlib.gunzipSync(payload);
console.log(result.toString("utf8"));
cb(null, {});
} catch (err) {
cb(err);
}
},
{ parent: this },
);
this.lambda = collector.lambda;
const region = aws.config.requireRegion();
const permission = new aws.lambda.Permission(name, {
action: "lambda:invokeFunction",
function: this.lambda,
principal: "logs." + region + ".amazonaws.com",
}, { parent: this });
}
}
new aws.ec2.RouteTableAssociation(`${baseName}-private-rta-${index + 1}`, {
subnetId: subnet.id,
routeTableId: privateRouteTable.id,
}, subnetParent);
return privateRouteTable;
});
const allRouteTables = [vpc.defaultRouteTableId, ...privateRouteTables.map(rt => rt.id)];
//
if (inputs.createS3Endpoint) {
new aws.ec2.VpcEndpoint(`${baseName}-s3-endpoint`, {
vpcId: vpc.id,
serviceName: `com.amazonaws.${aws.config.region}.s3`,
routeTableIds: allRouteTables,
}, vpcParent);
}
if (inputs.createDynamoDbEndpoint) {
new aws.ec2.VpcEndpoint(`${baseName}-dynamodb-endpoint`, {
vpcId: vpc.id,
serviceName: `com.amazonaws.${aws.config.region}.dynamodb`,
routeTableIds: allRouteTables,
}, vpcParent);
}
if (inputs.enableFlowLogs) {
const logGroupTags = Object.assign({
Name: `${inputs.description} VPC Flow Logs`,
}, inputs.baseTags);
function swaggerRouteHandler(lambdaArn: string) {
const region = aws.config.requireRegion();
return {
"x-amazon-apigateway-any-method": {
"x-amazon-apigateway-integration": {
uri: `arn:aws:apigateway:${region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations`,
passthroughBehavior: "when_no_match",
httpMethod: "POST",
type: "aws_proxy",
},
},
};
}
routeTableId: privateRouteTable.id,
destinationCidrBlock: "0.0.0.0/0",
gatewayId: natGateway.id,
}, privateRouteTableParent);
new aws.ec2.RouteTableAssociation(`${baseName}-private-rta-${index + 1}`, {
subnetId: subnet.id,
routeTableId: privateRouteTable.id,
}, subnetParent);
return privateRouteTable;
});
const allRouteTables = [vpc.defaultRouteTableId, ...privateRouteTables.map(rt => rt.id)];
//
if (inputs.createS3Endpoint) {
new aws.ec2.VpcEndpoint(`${baseName}-s3-endpoint`, {
vpcId: vpc.id,
serviceName: `com.amazonaws.${aws.config.region}.s3`,
routeTableIds: allRouteTables,
}, vpcParent);
}
if (inputs.createDynamoDbEndpoint) {
new aws.ec2.VpcEndpoint(`${baseName}-dynamodb-endpoint`, {
vpcId: vpc.id,
serviceName: `com.amazonaws.${aws.config.region}.dynamodb`,
routeTableIds: allRouteTables,
}, vpcParent);
}
if (inputs.enableFlowLogs) {
const logGroupTags = Object.assign({
Name: `${inputs.description} VPC Flow Logs`,
}, inputs.baseTags);
const logGroup = new aws.cloudwatch.LogGroup(`${baseName}-vpc-flow-logs`, {
tags: logGroupTags,