We have three components:
The components are decoupled with the AWS Systems Manager (SSM) Parameter Store. You could create all within one CDK App. But when you couple the CDK stacks together, deployment from stak A clould automatically deploy a dependent Stack B.
Most of the time that is OK, but sometimes you do not want the dependent stack automatically deployed. An example would be an EC2 instance stack, where the AMI of the instances is dynamically created. If the next time you deploy another stack, the EC2 instance stack would terminate the instances, because the AMI has changed, if there is a new AMI, e.g. of Amazon Linux.
So I decouple the stacks with the SSM Parameter Store.
/go-on-aws/vpc
vpcParm := "/go-on-aws/vpc"
awsssm.NewStringParameter(stack, &vpcParm,
&awsssm.StringParameterProps{
AllowedPattern: new(string),
Description: aws.String("VPC id go on aws architecture"),
ParameterName: &vpcParm,
StringValue: vpc.VpcId(),
})
To communicate with the ECS service from a private subnet, the vpc Stack is deployed with a NAT gateway. This costs 30$…40$ a month.
See infra/1-vpc/vpc.go
.
/go-on-aws/table
This value is also read by the application itselffunc GetTableName(client *ssm.Client) *string {
parms := &ssm.GetParameterInput{
Name: aws.String("/go-on-aws/table"),
}
resp, err := client.GetParameter(context.TODO(), parms)
if err != nil {
panic("ssm error, " + err.Error())
}
value := resp.Parameter.Value
return value
}
See app/parameter.go
.
The app uses the Gin web framework.
The container authentices with a basic web authentication:
basicAuth := gin.BasicAuth(gin.Accounts{
"go-on-aws": "hugo2021",
})
Therefore the health check of the load balancer has to interpret “401 Unauthorized” as healthy:
// 401 Unauthorized
stethoscope := albv2.HealthCheck{
Enabled: aws.Bool(true),
HealthyHttpCodes: aws.String("200,401"),
}
service.TargetGroup().ConfigureHealthCheck(&stethoscope)
See infra/3-container/fargate.go
.
Then a request /query is routed to a query function. This query calls Scan on dynamob.
Have docker running.
task build-app
This will build the app for target Linux with:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ../dist/dosshow -ldflags '-w' main/main.go
And copies the binary together with some static assets like the html and css files to a “dist” distribution directory. The CDK will call docker to build an image from the dist directory.
Export Account number for CDK
Get Account number:
aws sts get-caller-identity
Export as CDK_DEFAULT_ACCOUNT
export CDK_DEFAULT_ACCOUNT=555555555555
Replace the number with your account number.
Now you can call the tasks from the base directory, which is architectures/container
from the github repository.
task deploy-vpc
Calls an deploy inside directory infra/1-vpc
task deploy-table
Calls an deploy inside directory infra/2-table
task deploy-container
Calls an deploy inside directory infra/3-container
From the output of the fargate Service:
Cluster
✅ cluster
Outputs:
cluster.ALBFargoServiceLoadBalancerDNSD5AE4891 = clust-ALBFa-15F1YQU1QRKTS-498204716.eu-central-1.elb.amazonaws.com
cluster.ALBFargoServiceServiceURL4147A41A = http://clust-ALBFa-15F1YQU1QRKTS-498204716.eu-central-1.elb.amazonaws.com
cluster.LoadBalancerDNS = clust-ALBFa-15F1YQU1QRKTS-498204716.eu-central-1.elb.amazonaws.com
Stack ARN:
arn:aws:cloudformation:eu-central-1:669453403305:stack/cluster/409e7160-545d-11ec-a1b4-06686f469054
Call the cluster.ALBFargoServiceServiceURL… to get the password field. Use the credentials from app/main/main.go
.
Do not hardcode credentials in any app. This is just for educational purposes and is not meant to be used in production.
You could get the credentials from an encrypted Systems Manager Parameter.
To see data, you hav to put entries in the created DynamoDB.
Reverse order
task destroy-container
task destroy-table
task destroy-vpc
See the full source on github.