Skip to content

Commit

Permalink
Add Watchtower with docker compose, fix MOTD header
Browse files Browse the repository at this point in the history
  • Loading branch information
leoriviera committed Nov 27, 2023
1 parent 67e1c38 commit 38921d6
Show file tree
Hide file tree
Showing 21 changed files with 154 additions and 99 deletions.
3 changes: 3 additions & 0 deletions packages/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ testem.log
Thumbs.db

.nx/cache

# Build logs
build.log
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "nodemon src/index.ts",
"build": "tsc",
"dev:build": "docker build -t contained-server:dev -f Dockerfile.dev .",
"dev:start": "docker run -v $(realpath $pwd ./node_modules):/usr/src/app/node_modules -v $(pwd):/usr/src/app -v /var/run/docker.sock:/var/run/docker.sock -d -p 3000:3000 contained-server:dev",
"dev:start": "docker run -v $(realpath $pwd ./node_modules):/usr/src/app/node_modules -v $(pwd):/usr/src/app -v /var/run/docker.sock:/var/run/docker.sock -p 3000:3000 contained-server:dev",
"prod:build": "docker build --platform linux/amd64 -t ghcr.io/leoriviera/contained-server:latest .",
"prod:push": "docker push ghcr.io/leoriviera/contained-server:latest"
},
Expand Down
7 changes: 5 additions & 2 deletions packages/ssh/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ENV BLOG_GITHUB_REPO=$BLOG_GITHUB_REPO
LABEL com.centurylinklabs.watchtower.enable="false"

# Install packages
RUN apt update && apt install openssh-server sudo curl unzip sl rsync neofetch -y
RUN apt update && apt install openssh-server sudo curl unzip sl rsync neofetch moreutils gettext-base -y

# Create a user "sshuser" and group "sshgroup"
RUN groupadd usergroup && useradd -ms /bin/bash -g usergroup user
Expand All @@ -25,6 +25,9 @@ RUN echo 'eval "$(starship init bash)"' >> /home/user/.bashrc

COPY --chown=root etc /tmp-etc
RUN chmod 755 -R /tmp-etc/*
# As env vars aren't available in update-motd.d, replace env vars in etc/ files with envsubst
# Requires sponge from moreutils (see https://stackoverflow.com/a/74551579)
RUN find /tmp-etc -type f -exec sh -c "cat {} | envsubst | sponge {}" \;

# Remove existing message of the day
RUN rm /etc/update-motd.d/*
Expand All @@ -41,4 +44,4 @@ RUN service ssh start
# Expose docker port 22
EXPOSE 22

CMD timeout 3600 /usr/sbin/sshd -o "SetEnv=BLOG_GITHUB_REPO=$BLOG_GITHUB_REPO" -D
CMD timeout 3600 /usr/sbin/sshd -D
4 changes: 2 additions & 2 deletions packages/ssh/etc/update-motd.d/00-header
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
# Running code to fetch the blog content in profile.d doesn't work, as
# update-motd.d runs first. So, we'll just fetch the blog content here.
# to make sure the latest post is always displayed.

curl -s -L -o /home/user/blog.zip "$BLOG_GITHUB_REPO/archive/main.zip"
unzip -q /home/user/blog.zip -d /home/user
mv /home/user/blog-main /home/user/blog
rm /home/user/blog.zip
chown -R user /home/user/blog

printf "Welcome to my Terminal blog. I'm still thinking of a catchy name for it.\n"
# printf "If you've never used the terminal before, you can get started with [cat ~/help.md].\n"
printf "(You can click on any commands in square brackets, by the way, to run them automatically!)\n"
printf "\n"
printf "Check out the latest post at [cat ~/blog/$(ls -t /home/user/blog | head -1)]!\n"
printf "\n"`
printf "\n"
printf "Interested in hiring me? Check out my CV with [cat ~/cv/README.md].\n"
2 changes: 1 addition & 1 deletion packages/ssh/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "A simple SSH server that runs in a container",
"scripts": {
"dev:build": "docker build -t contained-ssh:dev .",
"dev:build": "docker build -t contained-ssh:dev . &> build.log",
"prod:build": "docker build --platform linux/amd64 -t ghcr.io/leoriviera/contained-ssh:latest .",
"prod:push": "docker push ghcr.io/leoriviera/contained-ssh:latest"
}
Expand Down
7 changes: 0 additions & 7 deletions terraform/frontend/main.tf

This file was deleted.

3 changes: 0 additions & 3 deletions terraform/frontend/outputs.tf

This file was deleted.

23 changes: 0 additions & 23 deletions terraform/frontend/variables.tf

This file was deleted.

2 changes: 1 addition & 1 deletion terraform/infrastructure/actions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ resource "github_actions_environment_variable" "aws_s3_bucket_name" {
environment = github_repository_environment.repo_env.environment
repository = data.github_repository.repo.name
variable_name = "AWS_S3_BUCKET_NAME"
value = var.s3_bucket_name
value = aws_s3_bucket.bucket.bucket
}

resource "github_actions_environment_variable" "aws_region" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ resource "aws_cloudfront_distribution" "cloudfront" {
origin_access_control_id = aws_cloudfront_origin_access_control.s3_access.id
}

aliases = [var.domain]
aliases = [var.frontend_domain]

default_cache_behavior {
compress = true
Expand All @@ -42,7 +42,7 @@ resource "aws_cloudfront_distribution" "cloudfront" {
}

viewer_certificate {
acm_certificate_arn = var.certificate_arn
acm_certificate_arn = aws_acm_certificate_validation.certificate.certificate_arn
ssl_support_method = "sni-only"
}

Expand All @@ -51,8 +51,8 @@ resource "aws_cloudfront_distribution" "cloudfront" {

# Create a record to point the front-end subdomain at the CloudFront distribution
resource "aws_route53_record" "frontend" {
zone_id = var.hosted_zone_id
name = "${var.domain}."
zone_id = data.aws_route53_zone.hosted_zone.zone_id
name = "${var.frontend_domain}."
type = "A"

alias {
Expand Down
31 changes: 27 additions & 4 deletions terraform/infrastructure/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ resource "aws_iam_policy" "s3_access_policy" {
Action = [
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObject",
"s3:ListBucket"
"s3:PutObject"
]
Resource = "arn:aws:s3:::${var.s3_bucket_name}/*"
Resource = "${aws_s3_bucket.bucket.arn}/*"
}
]
})
}

# Attach IAM policy to user
resource "aws_iam_user_policy_attachment" "test-attach" {
resource "aws_iam_user_policy_attachment" "s3_user_access" {
user = aws_iam_user.gh_action.name
policy_arn = aws_iam_policy.s3_access_policy.arn
}
Expand All @@ -34,3 +33,27 @@ resource "aws_iam_user_policy_attachment" "test-attach" {
resource "aws_iam_access_key" "gh_action" {
user = aws_iam_user.gh_action.name
}

data aws_iam_policy_document "ec2_assume_role" {
statement {
actions = ["sts:AssumeRole"]

principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}

resource "aws_iam_role" "ec2_iam_role" {
assume_role_policy = data.aws_iam_policy_document.ec2_assume_role.json
}

resource "aws_iam_role_policy_attachment" "s3_user_access" {
role = aws_iam_role.ec2_iam_role.name
policy_arn = aws_iam_policy.s3_access_policy.arn
}

resource "aws_iam_instance_profile" "instance_profile" {
role = aws_iam_role.ec2_iam_role.name
}
16 changes: 10 additions & 6 deletions terraform/infrastructure/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
output "availability_zones" {
value = local.availability_zones
}

output "certificate_arn" {
value = aws_acm_certificate_validation.certificate.certificate_arn
}
Expand All @@ -6,12 +10,8 @@ output "hosted_zone_id" {
value = data.aws_route53_zone.hosted_zone.zone_id
}

output "iam_user_arn" {
value = aws_iam_user.gh_action.arn
}

output "availability_zones" {
value = local.availability_zones
output "instance_profile_arn" {
value = aws_iam_instance_profile.instance_profile.arn
}

output "vpc_id" {
Expand All @@ -21,3 +21,7 @@ output "vpc_id" {
output "vpc_subnets" {
value = [for subnet in aws_subnet.public_subnets : subnet.id]
}

output "s3_bucket_name" {
value = aws_s3_bucket.bucket.bucket
}
25 changes: 20 additions & 5 deletions terraform/frontend/s3.tf → terraform/infrastructure/s3.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resource "aws_s3_bucket" "bucket" {
force_destroy = true
}

# Allow access to the S3 bucket through CloudFront
# Allow access to the S3 bucket through CloudFront, GitHub Actions and EC2
resource "aws_s3_bucket_policy" "allow_cloudfront_access" {
bucket = aws_s3_bucket.bucket.id
policy = jsonencode({
Expand All @@ -25,7 +25,7 @@ resource "aws_s3_bucket_policy" "allow_cloudfront_access" {
}
},
{
Sid = "AllowS3BucketAccess",
Sid = "AllowGitHubS3BucketAccess",
Effect = "Allow",
Action = [
"s3:GetObject",
Expand All @@ -35,20 +35,35 @@ resource "aws_s3_bucket_policy" "allow_cloudfront_access" {
Resource = "${aws_s3_bucket.bucket.arn}/*",
Principal = {
AWS = [
var.iam_user_arn
aws_iam_user.gh_action.arn
]
}
},
{
Sid = "AllowS3BucketAccess",
Sid = "AllowGitHubS3BucketAccess",
Effect = "Allow",
Action = [
"s3:ListBucket"
]
Resource = "${aws_s3_bucket.bucket.arn}",
Principal = {
AWS = [
var.iam_user_arn
aws_iam_user.gh_action.arn
]
}
},
{
Sid = "AllowEC2S3BucketAccess",
Effect = "Allow",
Action = [
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObject"
]
Resource = "${aws_s3_bucket.bucket.arn}/*",
Principal = {
AWS = [
aws_iam_role.ec2_iam_role.arn
]
}
}
Expand Down
17 changes: 8 additions & 9 deletions terraform/infrastructure/variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
data "aws_availability_zones" "all" {}

data "aws_cloudfront_cache_policy" "caching_policy" {
name = "Managed-CachingOptimized"
}

data "aws_ec2_instance_type_offerings" "available" {
for_each = toset(data.aws_availability_zones.all.names)

Expand All @@ -17,15 +21,15 @@ data "aws_ec2_instance_type_offerings" "available" {
location_type = "availability-zone"
}

data "github_repository" "repo" {
full_name = var.repository
}

data "aws_route53_zone" "hosted_zone" {
name = "${var.domain}."
private_zone = false
}

data "github_repository" "repo" {
full_name = var.repository
}

# Finding AZs which support particular instances
# https://stackoverflow.com/a/63728735
locals {
Expand Down Expand Up @@ -55,11 +59,6 @@ variable "server_domain" {
nullable = false
}

variable "s3_bucket_name" {
type = string
nullable = false
}

variable "aws_region" {
type = string
nullable = false
Expand Down
11 changes: 2 additions & 9 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module "infrastructure" {
frontend_domain = "${var.frontend_subdomain}.${var.domain}"
instance_type = var.instance_type
repository = var.repository
s3_bucket_name = module.frontend.s3_bucket_name
server_domain = "${var.server_subdomain}.${var.domain}"

providers = {
Expand All @@ -23,15 +22,9 @@ module "server" {
domain = "${var.server_subdomain}.${var.domain}"
hosted_zone_id = module.infrastructure.hosted_zone_id
instance_type = var.instance_type
instance_profile_arn = module.infrastructure.instance_profile_arn
s3_bucket_name = module.infrastructure.s3_bucket_name
vpc_id = module.infrastructure.vpc_id
vpc_subnets = module.infrastructure.vpc_subnets
}

module "frontend" {
source = "./frontend"

certificate_arn = module.infrastructure.certificate_arn
domain = "${var.frontend_subdomain}.${var.domain}"
hosted_zone_id = module.infrastructure.hosted_zone_id
iam_user_arn = module.infrastructure.iam_user_arn
}
2 changes: 1 addition & 1 deletion terraform/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ output "server_subdomain" {
}

output "s3_bucket_name" {
value = module.frontend.s3_bucket_name
value = module.infrastructure.s3_bucket_name
}
7 changes: 6 additions & 1 deletion terraform/server/asg.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ resource "aws_launch_template" "launch_template" {
image_id = tolist(data.aws_ami_ids.amazon_linux.ids)[0]
instance_type = var.instance_type
vpc_security_group_ids = [aws_security_group.scaling_group_sg.id]
user_data = filebase64("${path.module}/user-data.sh")
user_data = base64encode(templatefile("${path.module}/user-data.sh", {
bucket_name = var.s3_bucket_name
}))
iam_instance_profile {
arn = var.instance_profile_arn
}
update_default_version = true
block_device_mappings {
device_name = "/dev/xvda"
Expand Down
17 changes: 17 additions & 0 deletions terraform/server/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: "3"

services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 30
platform: linux/amd64
server:
image: ghcr.io/leoriviera/contained-server:latest
ports:
- "3000:3000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
platform: linux/amd64
Loading

0 comments on commit 38921d6

Please sign in to comment.