Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECS infrastructure with the Flagsmith task definition #4

Merged
merged 5 commits into from
Jun 28, 2023

Conversation

deltacodepl
Copy link
Contributor

Thanks for submitting a PR! Please check the boxes below:

  • I have filled in the "Changes" section below?
  • I have filled in the "How did you test this code" section below?

Changes

Added "flagsmith-on-ecs" subproject with Terraform code that spins up ECS Fargate test cluster with the Flagsmith basic task definition.
The project provides instant access to the Flagsmith instance under specified domain by adding the flagsmith prefix such as flagsmith.yourdomain.com

How did you test this code?

How to test this project

  1. Register AWS Route53 Hosted Zone
    for example yourdomain.com

  2. Generate certificate with AWS Certificate Manager
    with *.yourdomain.com pattern

  3. Define your variables such as certificate arn, hosted zone domain, and other desired settings in terraform.tfvars file

    route53_hosted_zone = "yourdomain.com"
    certificate_arn = "arn:aws:acm:"
  4. Generate plan for infrastructure terraform plan -out flagsmith.tfplan

  5. Apply infrastructure by running terraform apply flagsmith.tfplan

@khvn26
Copy link
Member

khvn26 commented Jun 1, 2023

This is awesome, @deltacodepl, thank you so much for your contribution! Bonus points for the docs 🔥

There are formatting issues detected in CI, any chance you could look into it?

@deltacodepl
Copy link
Contributor Author

Sure thing,
Thank you for your appreciation, Kim

Copy link

@plumdog plumdog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to be careful about what is being promised with this code.

If it is intended to be something that a user - a beginner with Terraform and AWS - could pick up and use to deploy their production environment, then I think the bar is very high. We'd need to accommodate lots of different options (things like the database sizing, database snapshotting, fargate resource allocation options and autoscaling, VPC and CIDR options etc) and absolutely need to be very careful with the IAM policies to reduce them to be least privilege.

Or, we could make very clear that this is a prove-to-yourself-and-your-boss-that-it-works example, but nothing more. Remove all references to "production" from this code and put a big warning at the top of the README to explain that this is not production ready, and that a user who is familiar with Terraform and AWS should use this as a reference to build their own solution.

# Listener (redirects traffic from the load balancer to the target group)
resource "aws_alb_listener" "ecs-alb-http-listener" {
load_balancer_arn = aws_lb.production.id
port = "443"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the load balancer SG allows 443 and 80, but there's only a 443 listener.

Suggest either:

  • 443 only on the listener, 443 only on the load balancer SG
  • 443 on the listener that forwards to the workload, 80 on the listener that redirects to 443, 443 and 80 on the load balancer SG (probably with a comment to say that 80 is only used for redirecting to 443)

Comment on lines 39 to 85
default_action {
type = "forward"
target_group_arn = aws_alb_target_group.default-target-group.arn
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've seen issues on ALB+ECS workloads, where requests like curl -k https://[load balancer ip] get to the load balancer and are forwarded, and generate lots of DisallowedHost errors from Django.

For this reason, think it is preferable here to have an action that matches on the expected host name, and forward that to the ALB target group. Then the default action is 404. As it happens, here is me suggesting this as an improvement in the CDK: aws/aws-cdk#25434.

load_balancer_arn = aws_lb.production.id
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be ELBSecurityPolicy-TLS13-1-0-2021-06, with a comment to say that the user should ensure it is appropriate for their usage, and use a newer one if available when they are deploying, see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies.

"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource" : "*"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be *?

Comment on lines 24 to 25
Action = ["secretsmanager:GetSecretValue", "ssm:GetParameters"],
Resource = ["arn:aws:ssm:${var.region}:${local.AWS_ACCOUNT_ID}:parameter/${var.app_name}/"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a secretsmanager:... permission action, but the resource is arn:aws:ssm:..., which looks wrong to me.

Comment on lines 6 to 12
resource "aws_route53_record" "subdomain" {
zone_id = data.aws_route53_zone.selected.zone_id
name = "${var.app_name}.${data.aws_route53_zone.selected.name}"
type = "CNAME"
ttl = "300"
records = [aws_lb.production.dns_name]
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason not to use an Alias record here?


resource "aws_db_subnet_group" "production" {
name = "main"
# subnet_ids = module.vpc.public_subnets
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line should probably go away, as I think we'd always want to encourage using private subnets for a database.

password = aws_ssm_parameter.db_password.value
port = "5432"
engine = "postgres"
engine_version = "11.12"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason not to use a newer Postgres?

@@ -0,0 +1 @@
## Fargate autoscaling
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this to be removed, or should there be some resources here?

Comment on lines 6 to 21
"Action": [
"ecs:*",
"elasticloadbalancing:Describe*",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets",
"cloudwatch:*",
"s3:*",
"rds:*",
"logs:*",
"elasticache:*",
"secretsmanager:*",
"ssm:*"
],
"Resource": "*"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very permissive. Could this be pruned?

@deltacodepl
Copy link
Contributor Author

Hi @plumdog
Thank you for the review
I have cleaned up the code, tightened IAM permissions, and removed unnecessary elements based on all your suggestions.

Copy link

@plumdog plumdog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Thanks for applying the changes, this looks great, thanks for the hard work.

I must confess I haven't run it though (I feel like someone Flagsmith-side should actually run this code at least once before we merge... [looks around for volunteers...])

khvn26
khvn26 previously approved these changes Jun 21, 2023
flagsmith-on-ecs/terraform/variables.tf Outdated Show resolved Hide resolved
flagsmith-on-ecs/terraform/variables.tf Show resolved Hide resolved
flagsmith-on-ecs/terraform/variables.tf Outdated Show resolved Hide resolved
@khvn26
Copy link
Member

khvn26 commented Jun 21, 2023

It works, with some minor comments I've added. @deltacodepl I'll leave those for a bit of time in case you want to address them. Otherwise, I'll merge the PR and fix those myself. Again, many thanks for your work! Great job! 👍

@dabeeeenster
Copy link
Contributor

Yep thanks again for this @deltacodepl

@khvn26 khvn26 merged commit c38d6f9 into Flagsmith:main Jun 28, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants