Hosting and CI - Teknikio/pxt-teknikio GitHub Wiki
This project contains Teknikio MakeCode project that is deployed to ECS via CircleCI using Docker containers.
Requirements
Environment Variables
AWS_ACCOUNT_ID . = ''
AWS_ACCESS_KEY_ID = ''
AWS_SECRET_ACCESS_KEY = ''
AWS_RESOURCE_PREFIX = "pxt-teknikio"
AWS Setup
-
Install AWS CLI
pip3 install awscli --upgrade --user
-
Configure AWS, run the following and follow the steps
aws configure
-
APPLICATION_ID, APPLICATION_SECRET are generated when an access key is created. Take care of these, and never commit or post.
Creating a Dockerfile
This Docker image must load all environment dependencies, compile the project and specify a launch command for services.
-
Install Docker
-
All docker files must start with
FROM
, importing Base image. -
The unzip commands are Play! specific, copying project plugins definitions to root location
FROM node:10-stretch # ~~~ Environment vars ENV NODE_ENV production ENV PORT 3232 # ~~~ # ~~~ Bundle app source WORKDIR /usr/src/app/tmp COPY . ./ # ~~~ # ~~~ Install app dependencies & create static build package & clean up RUN npm install -g pxt \ && npm install -g http-server \ && npm install \ && pxt staticpkg \ && mv built/packaged/* /usr/src/app \ && rm -rf /usr/src/app/tmp # ~~~
-
Most critical part is specifying the proper entry point to run the application. We do not want to use
pxt serve
for remote environments, and simple want to host static output# ~~~ Expose the port from this container EXPOSE ${PORT} # ~~~ # ~~~ Load static package running web server WORKDIR /usr/src/app ENTRYPOINT ["http-server", "-c-1", "."] # ~~~
- Reference Dockerfile
Building, running and deploying Docker images to ECR
-
Create an example ECR repository to hold (for the purposes of the next couple of steps)
aws ecr create-repository --repository-name pxt-teknikio-scala
-
Build local Docker image an example ECR repository to hold
docker build -t pxt-teknikio .
-
Run the docker file
docker run -p 3232:3232 pxt-teknikio:latest
-
Tag the local Docker image
docker tag pxt-teknikio:latest ${REPOSITORY_URL}/pxt-teknikio:latest
-
Push this Docker image to ECR
$(aws ecr get-login --no-include-email --region us-east-2) docker push ${REPOSITORY_URL}/pxt-teknikio:latest
CircleCI
-
Project configuration
Environment Variables AWS_ACCESS_KEY_ID xxxxIQZQ AWS_ACCOUNT_ID xxxx6476 AWS_DEFAULT_REGION xxxxst-2 AWS_ECR_ACCOUNT_URL xxxx.com AWS_RESOURCE_NAME_PREFIX xxxxikio AWS_SECRET_ACCESS_KEY xxxxORGh
-
Using Orbs - Simplify configs by leveraging circleci built in and community orbs, with discretion
version: 2.1 machine: timezone: UTC java: version: oraclejdk11 orbs: aws-ecr: circleci/[email protected] aws-ecs: circleci/[email protected]
Workflow
2. Build and push docker image
3. Update AWS Service
-
Build and push docker image Attaching to workspace is key to pick up our output from previous step, we do not want a fresh checkout
- aws-ecr/build_and_push_image: account-url: AWS_ECR_ACCOUNT_URL aws-access-key-id: AWS_ACCESS_KEY_ID aws-secret-access-key: AWS_SECRET_ACCESS_KEY repo: "${AWS_RESOURCE_NAME_PREFIX}-${AWS_RESOURCE_NAME_SUFFIX}" region: AWS_DEFAULT_REGION tag: "${CIRCLE_SHA1}" attach-workspace: true workspace-root: ~/project checkout: false
-
Update ECS service
- aws-ecs/deploy-service-update: family: "${AWS_RESOURCE_NAME_PREFIX}-service-${AWS_RESOURCE_NAME_SUFFIX}" cluster-name: "${AWS_RESOURCE_NAME_PREFIX}-cluster-${AWS_RESOURCE_NAME_SUFFIX}" container-image-name-updates: "container=${AWS_RESOURCE_NAME_PREFIX}-service-${AWS_RESOURCE_NAME_SUFFIX},image-and- tag=${AWS_ECR_ACCOUNT_URL}/${AWS_RESOURCE_NAME_PREFIX}-${AWS_RESOURCE_NAME_SUFFIX}:${CIRCLE_SHA1}" verify-revision-is-deployed: true
-
Reference CircleCI config
AWS Stack & CloudFormations
CloudFormations
-
In this example Cloudformation stacks consist of two Clusters, one that is running EC2 capabilities, and one that is running on FARGATE capabilities
-
FARGATE clusters are reserved for Production and Staging environments whereas EC2 clusters are used for integration and sandbox environments where instance access can serve useful.
Terraform
-
Install Terraform and add to PATH
-
variables.tf
variable "aws_access_key" {} variable "aws_secret_key" {} variable "aws_account_id" {} variable "aws_region" { description = "AWS region e.g. us-east-1 (Please specify a region supported by the Fargate launch type)" } variable "aws_resource_prefix" { description = "Prefix to be used in the naming of some of the created AWS resources e.g. demo-webapp" }
-
To build stack
terraform init terraform plan terraform apply
-
Reference terraform CircleCI config
Troubleshooting
-
ECS updates and terraform execution
https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-custom-name/