A Terraform module to provision appmixer application.
Autoscaling is configured using ecs_autoscaling_config
variable which by default defines two capacity providers used while scaling the cluster.
on_demand
- capacity provider alocates on demand EC2 instances which are more expensive but are always availablespot
- capacity provider alocates spot EC2 instances which are cheaper but can be terminated at any time, therefore it is recommended to use spot instances as temporary capacity
To see more info about capacity provider configuration see aws_autoscaling_group configuration
Important
Correct Instance types need to be set. The size of EC2 network interfaces (ENIs) for each instance type is restricted and this limitation is directly tied to the number of containers that can be executed on the instance. To avoid this limitation, consider using instance types that allow so-called ENI Trunking
meaning EC2 can attach more network interfaces (see more AWS Docs) Also ENI Trunking must be allowed in AWS account (AWS ECS -> Account Settings -> AWSVPC Trunking -> Enable)
RabbitMQ, Opensearch (Elasticsearch), ElasticCache (Redis), DocumentDB(Mongo) are managed by AWS and can be configured through variables:
document_db
elasticache
elasticsearch
rabbitmq
Each service is running with minimal configuration, in production they might need some resizing.
Note
Within this module, managed services can be created separately and incorporated using the e.g. external_elasticache
variable, for instance. It is crucial in this setup to verify the correct configuration of all network and security policies.
Admin user is initialized through automated task running in ECS. Variable init_user
needs to be set.
- the service
engine
is waiting for creation of index in DocumentDB which might take around 20min till service become available, therefore the User initialization will fail and needs to be repeated by runningterraform plan
again
- See Development example for further information. (Minimal setup)
- See Production example for further information. (High available setup)
AWS Pricing estimation for each environemnt. Pricing can vary based on real traffic.
- Development ~ 450$/month
- Production ~ 900$/month
You can use sshuttle to connect to private VPC network.
- Run EC2 with configured SSH keys in your public subnet
- Install
sshuttle
- Connect through
sshuttle
to your running EC2 (sshuttle -r <SSH_CONFIG> 0.0.0.0/0 -vv
) - Your network traffic should be routed through EC2, you should be able to see managed AWS services running in private subnets.
Name | Version |
---|---|
terraform | >= 1.6.6 |
aws | >= 5.32.1 |
http | 3.4.1 |
random | >= 3.6.0 |
Name | Source | Version |
---|---|---|
alb | terraform-aws-modules/alb/aws | ~> 9.0 |
autoscaling | terraform-aws-modules/autoscaling/aws | ~> 6.5 |
autoscaling_sg | terraform-aws-modules/security-group/aws | ~> 5.0 |
document_db_ssm_password | cloudposse/ssm-parameter-store/aws | 0.11.0 |
document_db_ssm_username | cloudposse/ssm-parameter-store/aws | 0.11.0 |
documentdb_cluster | cloudposse/documentdb-cluster/aws | 0.24.0 |
ecs_cluster | terraform-aws-modules/ecs/aws//modules/cluster | 5.7.4 |
ecs_service_backoffice | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |
ecs_service_engine | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |
ecs_service_frontend | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |
ecs_service_logstash | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |
ecs_service_quota | terraform-aws-modules/ecs/aws//modules/service | 5.7.4 |
elasticache | cloudposse/elasticache-redis/aws | 1.0.0 |
elasticache_ssm_password | cloudposse/ssm-parameter-store/aws | 0.11.0 |
elasticsearch | cloudposse/elasticsearch/aws | 0.46.0 |
elasticsearch_ssm_password | cloudposse/ssm-parameter-store/aws | 0.11.0 |
elasticsearch_ssm_username | cloudposse/ssm-parameter-store/aws | 0.11.0 |
label | cloudposse/label/null | 0.25.0 |
rabbit_mq | cloudposse/mq-broker/aws | 3.1.0 |
s3_bucket | cloudposse/s3-bucket/aws | 4.0.1 |
services_configuration_merge | cloudposse/config/yaml//modules/deepmerge | 1.0.2 |
sg_document_db_rules | cloudposse/security-group/aws | 2.2.0 |
sg_user_init | cloudposse/security-group/aws | 2.2.0 |
sq_elasticsearch | cloudposse/security-group/aws | 2.2.0 |
subnets | cloudposse/dynamic-subnets/aws | 2.4.1 |
vpc | cloudposse/vpc/aws | 2.1.1 |
Name | Type |
---|---|
aws_acm_certificate.alb | resource |
aws_acm_certificate_validation.this | resource |
aws_cloudwatch_log_group.ecs_mongo_init_user | resource |
aws_ecs_task_definition.this | resource |
aws_elasticsearch_domain_policy.this | resource |
aws_route53_record.alb | resource |
aws_route53_record.cert_alb | resource |
aws_service_discovery_http_namespace.appmixer | resource |
random_password.elasticsearch_password | resource |
random_password.rabbit_mq | resource |
random_password.redis_password | resource |
random_pet.document_db_username | resource |
random_pet.elasticsearch_username | resource |
aws_ecs_task_execution.run | data source |
aws_region.current | data source |
aws_ssm_parameter.ecs_optimized_ami | data source |
aws_vpc.external | data source |
http_http.init_user | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
root_dns_name | Root DNS name, must be applicable to route53 zone (zone_id) | string |
n/a | yes |
additional_security_group_rules | Additional security group rules added to security group rules of all resources, see more Terraform docs | list(object({ |
[] |
no |
alb_ingress_security_group_rules | Application Load Balancer security group ingress rules | map(object({ |
{ |
no |
attributes | Additional attributes (e.g. 1 ) |
list(string) |
[] |
no |
availability_zones | List of availability zones | list(string) |
[ |
no |
certificate_arn | Certificate ARN, if not set, certificate will be automatically created using '*.<root_dns_name>' | string |
null |
no |
document_db | DocumentDB configuration object | object({ |
{} |
no |
ecs_autoscaling_config | n/a | any |
{ |
no |
ecs_cluster_config | Cluster configuration object execute_command_configuration , see more terraform docs |
any |
{ |
no |
ecs_common_service_config | ECS service configuration: - ordered_placement_strategy defines how tasks are placed on instances, see more AWS docs or Terraform docs- force_new_deployment force service redeployment- wait_for_steady_state terraform apply waits for service to reach steady state, see more Terraform docs |
object({ |
{} |
no |
ecs_per_service_config | Configuration per service, overrides 'ecs_common_service_config' Example: { |
any |
{} |
no |
ecs_registry_auth_data | Docker registry credentials, base64 encoded string | string |
"" |
no |
elasticache | Elastic module configuration object | object({ |
{} |
no |
elasticsearch | Elasticsearch module configuration object | object({ |
{ |
no |
enable_deletion_protection | Enable deletion protection for all managed resources, if true, resources can't be deleted if not explicitly set to false | bool |
true |
no |
environment | Environment, e.g. 'prod', 'staging', 'dev', 'pre-prod', 'UAT' | string |
"dev" |
no |
external_documentdb | Connection string to DocumentDB, if not set, DocumentDB will be automatically created | string |
null |
no |
external_elasticsearch | Connection object to Elasticsearch, if not set, Elasticsearch will be automatically created | object({ |
null |
no |
external_rabbitmq | Connection object to RabbitMQ, if not set, RabbitMQ will be automatically created | object({ |
null |
no |
external_redis | Connection string to Redis, if not set, Redis will be automatically created | string |
null |
no |
external_vpc | VPC configuration, if not set, new VPC will be created | object({ |
null |
no |
init_user | Initial user created in appmixer. Creation through appmixer API and by setting up admin scope in documentdb directly | object({ |
null |
no |
name | Solution name, e.g. 'appmixer' | string |
"appmixer" |
no |
namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | string |
"cio" |
no |
rabbitmq | RabbitMQ module configuration object | object({ |
{} |
no |
s3_config | Configuration for S3 bucket | object({ |
{} |
no |
stage | Stage, e.g. 'prod', 'staging', 'dev' | string |
"" |
no |
tags | Additional tags (e.g. map('BusinessUnit','XYZ') |
map(string) |
{} |
no |
vpc_config | VPC configuration, ignored if external_vpc is set |
object({ |
{ |
no |
zone_id | Route53 DNS zone ID, if not set AWS route53 will be not used | string |
null |
no |
Name | Description |
---|---|
alb_dns_name | DNS name of the ALB |
managed_services | Managed services configuration containing endpoints and name of SSM parameters with credentials |
services_urls | URLs of the running services |
vpc_config | VPC configuration contaning VPC ID, CIDR block and subnets |
Feel free to create an issue in this repository if you have questions, suggestions or feature requests.
We want to provide high quality code and modules. For this reason we are using several pre-commit hooks and GitHub Actions workflows. A pull-request to the main branch will trigger these validations and lints automatically. Please check your code before you will create pull-requests. See pre-commit documentation and GitHub Actions documentation for further details.
See LICENSE for full details.
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.