Skip to content

Commit

Permalink
Merge pull request #20 from werniq/feature/aws-cdk
Browse files Browse the repository at this point in the history
Pull Request: Add AWS CDK EKS Stack for GoGator Project
  • Loading branch information
werniq authored Oct 2, 2024
2 parents 8683115 + 05abf77 commit 0483548
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ bin/*
.idea
coverage
cover
*.tgz
*.tgz
19 changes: 19 additions & 0 deletions infra/aws/cdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# go.sum should be committed
!go.sum

# CDK asset staging directory
.cdk.staging
cdk.out
12 changes: 12 additions & 0 deletions infra/aws/cdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Welcome to your CDK Go project!

This is a blank project for CDK development with Go.

The `cdk.json` file tells the CDK toolkit how to execute your app.

## Useful commands

* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk synth` emits the synthesized CloudFormation template
* `go test` run unit tests
183 changes: 183 additions & 0 deletions infra/aws/cdk/aws-cdk-setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package main

import (
awscdk "github.com/aws/aws-cdk-go/awscdk/v2"
ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
eks "github.com/aws/aws-cdk-go/awscdk/v2/awseks"
iam "github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
)

type AwsSetupStackProps struct {
awscdk.StackProps
}

const (
// CoreDnsAddonVersion is the version of the CoreDNS addon to install.
CoreDnsAddonVersion = "v1.11.3-eksbuild.1"

// KubeProxyAddonVersion is the version of the kube-proxy addon to install.
KubeProxyAddonVersion = "v1.30.0-eksbuild.3"

// AmazonVpcCniAddonVersion is the version of the Amazon VPC CNI addon to install.
AmazonVpcCniAddonVersion = "v1.18.1-eksbuild.3"

// PodIdentityAddonVersion is the version of the EKS pod identity addon to install.
PodIdentityAddonVersion = "v1.3.2-eksbuild.2"
)

func NewGoGatorCdkProjectStack(scope constructs.Construct, id string, props *AwsSetupStackProps) awscdk.Stack {
stack := awscdk.NewStack(scope, &id, &props.StackProps)

vpc := ec2.NewVpc(stack, jsii.String("GoGatorVpc"), &ec2.VpcProps{
EnableDnsSupport: jsii.Bool(true),
EnableDnsHostnames: jsii.Bool(true),
MaxAzs: jsii.Number(2),
SubnetConfiguration: &[]*ec2.SubnetConfiguration{
{
Name: jsii.String("GoGatorSubnet1"),
CidrMask: jsii.Number(24),
SubnetType: ec2.SubnetType_PRIVATE_WITH_EGRESS,
},
{
Name: jsii.String("GoGatorSubnet2"),
CidrMask: jsii.Number(24),
SubnetType: ec2.SubnetType_PUBLIC,
},
},
})

sg := ec2.NewSecurityGroup(stack, jsii.String("GoGatorSecurityGroup"), &ec2.SecurityGroupProps{
Vpc: vpc,
SecurityGroupName: jsii.String("Go-Gator-Security-Group"),
Description: jsii.String("Allow inbound traffic from port 22 and 443"),
AllowAllOutbound: jsii.Bool(true),
})
sg.AddIngressRule(ec2.Peer_AnyIpv4(),
ec2.Port_Tcp(jsii.Number(22)),
jsii.String("Allow SSH"),
jsii.Bool(true))
sg.AddIngressRule(ec2.Peer_AnyIpv4(),
ec2.Port_Tcp(jsii.Number(443)),
jsii.String("Allow HTTPS"),
jsii.Bool(true))

subnet2RouteTable := ec2.NewCfnRouteTable(stack, jsii.String("GoGatorRouteTable2"), &ec2.CfnRouteTableProps{
VpcId: vpc.VpcId(),
})
ec2.NewCfnRoute(stack, jsii.String("GoGatorRoute2"), &ec2.CfnRouteProps{
RouteTableId: subnet2RouteTable.Ref(),
DestinationCidrBlock: jsii.String("0.0.0.0/0"),
GatewayId: vpc.InternetGatewayId(),
})

subnets := vpc.PublicSubnets()
subnet := (*subnets)[0]

ec2.NewCfnSubnetRouteTableAssociation(stack, jsii.String("GoGatorSubnet2RouteTableAssociation"), &ec2.CfnSubnetRouteTableAssociationProps{
SubnetId: subnet.SubnetId(),
RouteTableId: subnet2RouteTable.Ref(),
})

eksRole := iam.NewRole(stack, jsii.String("EksClusterRole"), &iam.RoleProps{
AssumedBy: iam.NewServicePrincipal(jsii.String("eks.amazonaws.com"), nil),
ManagedPolicies: &[]iam.IManagedPolicy{
iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonEKSClusterPolicy")),
iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonEKSServicePolicy")),
},
})

cluster := eks.NewCluster(stack, jsii.String("NewsAggregatorCluster"), &eks.ClusterProps{
ClusterName: jsii.String("NewsGoGatorCluster"),
Version: eks.KubernetesVersion_V1_30(),
Vpc: vpc,
Role: eksRole,
DefaultCapacity: jsii.Number(0),
EndpointAccess: eks.EndpointAccess_PUBLIC_AND_PRIVATE(),
})

userName := "oleksandr"
iamUserArn := "arn:aws:iam::406477933661:user/" + userName
cluster.AwsAuth().AddUserMapping(iam.User_FromUserArn(stack, jsii.String(userName), jsii.String(iamUserArn)), &eks.AwsAuthMapping{
Username: jsii.String(userName),
Groups: &[]*string{
jsii.String("system:masters"),
},
})

eks.NewCfnAddon(stack, jsii.String("GoGatorCoreDnsAddon"), &eks.CfnAddonProps{
ClusterName: cluster.ClusterName(),
AddonName: jsii.String("coredns"),
AddonVersion: jsii.String(CoreDnsAddonVersion),
})

eks.NewCfnAddon(stack, jsii.String("GoGatorKubeProxyAddon"), &eks.CfnAddonProps{
ClusterName: cluster.ClusterName(),
AddonName: jsii.String("kube-proxy"),
AddonVersion: jsii.String(KubeProxyAddonVersion),
})

eks.NewCfnAddon(stack, jsii.String("GoGatorVpcCniAddon"), &eks.CfnAddonProps{
ClusterName: cluster.ClusterName(),
AddonName: jsii.String("vpc-cni"),
AddonVersion: jsii.String(AmazonVpcCniAddonVersion),
})

eks.NewCfnAddon(stack, jsii.String("GoGatorEksPodIdentityAddon"), &eks.CfnAddonProps{
AddonName: jsii.String("eks-pod-identity-agent"),
ClusterName: cluster.ClusterName(),
AddonVersion: jsii.String(PodIdentityAddonVersion),
})

nodeGroupRole := iam.NewRole(stack, jsii.String("node-group-role"), &iam.RoleProps{
AssumedBy: iam.NewServicePrincipal(jsii.String("ec2.amazonaws.com"), nil),
Description: jsii.String("Role for EKS Node Group"),
ManagedPolicies: &[]iam.IManagedPolicy{
iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonEC2ContainerRegistryReadOnly")),
iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonEC2FullAccess")),
iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonEKS_CNI_Policy")),
iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonEKSWorkerNodePolicy")),
},
RoleName: jsii.String("GoGatorNodeGroupRoleAdmin"),
})

cluster.AddNodegroupCapacity(jsii.String("GoGatorNodeGroup"), &eks.NodegroupOptions{
DesiredSize: jsii.Number(1),
MaxSize: jsii.Number(5),
MinSize: jsii.Number(1),
NodegroupName: jsii.String("GoGatorNodeGroup"),
NodeRole: nodeGroupRole,
RemoteAccess: &eks.NodegroupRemoteAccess{
SshKeyName: jsii.String("Go-Gator-Client-Keys"),
},
Subnets: &ec2.SubnetSelection{
Subnets: subnets,
},
})

return stack
}

func main() {
defer jsii.Close()

app := awscdk.NewApp(nil)

NewGoGatorCdkProjectStack(app, "NewsAggregatorAwsSetupStack", &AwsSetupStackProps{
awscdk.StackProps{
Env: env(),
},
})

app.Synth(nil)
}

// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func env() *awscdk.Environment {
return &awscdk.Environment{
Account: jsii.String("406477933661"),
Region: jsii.String("us-east-2"),
}
}
95 changes: 95 additions & 0 deletions infra/aws/cdk/aws-cdk-setup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package main

import (
"testing"

"github.com/aws/aws-cdk-go/awscdk/v2"
"github.com/aws/aws-cdk-go/awscdk/v2/assertions"
"github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
"github.com/aws/aws-cdk-go/awscdk/v2/awseks"
"github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
)

func TestGoGatorCdkProjectStack(t *testing.T) {
app := awscdk.NewApp(nil)

stack := NewGoGatorCdkProjectStack(app, "TestStack", &AwsSetupStackProps{
awscdk.StackProps{
Env: env(),
},
})
template := assertions.Template_FromStack(stack, nil)

template.HasResourceProperties(awsec2.CfnVPC_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"EnableDnsSupport": true,
"EnableDnsHostnames": true,
})

template.HasResourceProperties(awsec2.CfnSecurityGroup_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"SecurityGroupIngress": []interface{}{
map[string]interface{}{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"CidrIp": "0.0.0.0/0",
},
map[string]interface{}{
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"CidrIp": "0.0.0.0/0",
},
},
})

template.HasResource(awsiam.CfnRole_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{})

template.HasResource(awseks.CfnAddon_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"Properties": map[string]interface{}{
"AddonName": "coredns",
"AddonVersion": "v1.11.3-eksbuild.1",
"ClusterName": map[string]string{
"Ref": "NewsAggregatorClusterDDE6C3E5",
},
},
})

template.HasResource(awseks.CfnAddon_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"Properties": map[string]interface{}{
"AddonName": "kube-proxy",
"AddonVersion": "v1.30.0-eksbuild.3",
"ClusterName": map[string]string{
"Ref": "NewsAggregatorClusterDDE6C3E5",
},
},
})

template.HasResource(awseks.CfnAddon_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"Properties": map[string]interface{}{
"AddonName": "eks-pod-identity-agent",
"AddonVersion": "v1.3.2-eksbuild.2",
"ClusterName": map[string]string{
"Ref": "NewsAggregatorClusterDDE6C3E5",
},
},
})

template.HasResource(awseks.CfnAddon_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"Properties": map[string]interface{}{
"AddonName": "vpc-cni",
"AddonVersion": "v1.18.1-eksbuild.3",
"ClusterName": map[string]string{
"Ref": "NewsAggregatorClusterDDE6C3E5",
},
},
})

template.HasResourceProperties(awseks.CfnNodegroup_CFN_RESOURCE_TYPE_NAME(), map[string]interface{}{
"NodegroupName": "GoGatorNodeGroup",
"ScalingConfig": map[string]interface{}{
"DesiredSize": 1,
"MinSize": 1,
"MaxSize": 5,
},
})
}
15 changes: 15 additions & 0 deletions infra/aws/cdk/cdk.context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"availability-zones:account=406477933661:region=us-east-2": [
"us-east-2a",
"us-east-2b",
"us-east-2c"
],
"availability-zones:account=406477933661:region=us-east-1": [
"us-east-1a",
"us-east-1b",
"us-east-1c",
"us-east-1d",
"us-east-1e",
"us-east-1f"
]
}
Loading

0 comments on commit 0483548

Please sign in to comment.