Problems with containerdefinition in aws to work with secrets - terraform

I have a containerdefinition to populate tasks in a cluster, like this one, I'm trying just two things, first of all with a command I want to write a simple hello to my index.html:
[ {
"name": "cb-app",
"image": "${app_image}",
"cpu": ${fargate_cpu},
"memory": ${fargate_memory},
"networkMode": "awsvpc",
"command":[
"bin/sh -c \"echo 'hola222' > /usr/share/nginx/html/index.html\""
],
"entryPoint": [
"sh",
"-c"
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/cb-app",
"awslogs-region": "${aws_region}",
"awslogs-stream-prefix": "ecs"
}
},
"secrets": [
{
"name": "USERNAME2_VALUE",
"valueFrom": "arn:aws:secretsmanager:xxxxx:xxxxxxx:secret:USERNAME2_VALUE-ipilBA"
}
],
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
},
{
"containerPort": 22,
"hostPort": 22
}
]
}
]
I have an ecr with a simple nginx-alpine image. If I work without the entryPoint and command, it works fine and it shows the first page of the webserver but when I write the entryPoing and command. It doesn't work and I don't know why. I am using fargate. Could you help me?. Thanks a lot.
When I write the command and entryPoint all task stop and I have an exitCode 0.
This is what I have and I don't have any kind of log
As well, I get STOPPED (Essential container in task exited) on the tasks which were stopped

Related

Must include AWSEBDockerrunVersion key in the Dockerrun.aws.json file

Trying to move my Docker Compose application to Elastic Beanstalk and having some issues.
Been struggling with this for like a week now, come pretty far but still some big issues. I converted my docker-compose.yml to a Dockerrun.aws.json using container transform:
{
"AWSEBDockerrunVersion": 2,
"containerDefinitions": [
{
"entryPoint": [
"/client/entrypoint.sh"
],
"essential": true,
"memory": 512,
"image": "nodejs",
"links": [
"server_dans_backend:server_dans_backend"
],
"name": "client_dans_backend",
"portMappings": [
{
"containerPort": 3000,
"hostPort": 3000
}
]
},
{
"environment": [
{
"name": "POSTGRES_DB",
"value": "ABC"
},
{
"name": "POSTGRES_USER",
"value": "ABC"
},
{
"name": "POSTGRES_PASSWORD",
"value": "ABC"
},
{
"name": "POSTGRES_HOST",
"value": "ABC"
}
],
"essential": true,
"image": "postgres:14-alpine",
"memory": 512,
"name": "db_dans_backend",
"portMappings": [
{
"containerPort": 5432,
"hostPort": 5432
}
]
},
{
"essential": true,
"image": "nginx:alpine",
"memory": 512,
"links": [
"server_dans_backend",
"client_dans_backend"
],
"name": "nginx_dans_backend",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
]
},
{
"entryPoint": [
"/app/server/entrypoint.sh"
],
"essential": true,
"image": "alpine:python",
"memory": 512,
"links": [
"db_dans_backend:db_dans_backend"
],
"name": "server_dans_backend",
"portMappings": [
{
"containerPort": 8000,
"hostPort": 8000
}
]
}
]
}
Pretty straightforward - Node (NextJS), Python (Django), Nginx and Postgres
My problem is this, it doesn't work in prod and whenever I try eb local run I get the following error:
ERROR: ValidationError - The AWSEBDockerrunVersion key in the Dockerrun.aws.json file is not valid or is not included.
Even weirder, when I actually eb deploy I get this:
Instance deployment: 'Dockerrun.aws.json' in your source bundle specifies an unsupported version. Elastic Beanstalk only supports version 1 for non compose app and version 3 for compose app. The deployment failed.
But there is no version 3 for this file format.
I'm not particularly sure why this is a problem though since the key is clearly included. I read it could be a problem if your EB platform isn't multidocker but I believe my platform is correct.
When I run eb platform show I get the following:
64bit Amazon Linux 2 v3.4.16 running Docker
which I believe is valid - the only other option would be the ECS+EB option which I don't believe works with eb local run anyway.
Thank you in advance, been really struggling with this.

How to concatenate two template files into one file and pass onto ECS container task definition in terraform

I have two template files. I want to merge these template files into one and pass them onto the ECS attribute container_definitions in the aws_ecs_task_definition resource.
Terraform Version => v0.14.9
nginx.tpl.json:
[
{
"name": "nginx",
"image": "public.ecr.aws/nginx/nginx:latest",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
]
}
]
redis.json.tpl:
[
{
"name": "redis",
"image": "public.ecr.aws/peakon/redis:6.0.5",
"portMappings": [
{
"containerPort": 6379,
"hostPort": 6379,
"protocol": "tcp"
}
]
}
]
When combined two template files manually like below it is working. But with Terraform concat or format getting errors.
[
{
"name": "nginx",
"image": "public.ecr.aws/nginx/nginx:latest",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
]
},
{
"name": "redis",
"image": "public.ecr.aws/peakon/redis:6.0.5",
"portMappings": [
{
"containerPort": 6379,
"hostPort": 6379,
"protocol": "tcp"
}
]
}
]
data "template_file" "ecs_task" {
template = format("%s%s",file("./ecs/templates/nginx.json.tpl"),
file("./ecs/templates/redis.json. tpl")
)
} => Here I need to combine the two template files and then pass them onto the container_definitions to the below resource.
resource "aws_ecs_task_definition" "testapp" {
family = "testapp"
network_mode = "awsvpc"
cpu = 256
memory = 512
container_definitions = data.template_file.ecs_task.rendered # I'm getting the following error.
}
Error:invalid character '}' looking for the beginning of object key string
Can someone help me with this, please?
Update
Remove brackets from your files
{
"name": "nginx",
"image": "public.ecr.aws/nginx/nginx:latest",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
]
}
and
{
"name": "redis",
"image": "public.ecr.aws/peakon/redis:6.0.5",
"portMappings": [
{
"containerPort": 6379,
"hostPort": 6379,
"protocol": "tcp"
}
]
}
Then instead of "%s%s". Seems you are missing comma: "[%s,%s]".

How do I run a node container on AWS ECS without exiting

I'm struggling to keep my node.js container running on ECS. It runs fine when I run it locally with docker compose, but on ECS it runs for a 2-3 mins and handles a few connections (2-3 health checks from the load balancer), then closes down. And I can't work out why.
My Dockerfile -
FROM node:6.10
RUN npm install -g nodemon \
&& npm install forever-monitor \
winston \
express-winston
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 3000
CMD [ "npm", "start" ]
Then in my package.json -
{
...
"main": "forever.js",
"dependencies": {
"mongodb": "~2.0",
"abbajs": ">=0.1.4",
"express": ">=4.15.2"
}
...
}
In my docker-compose.yml I run with nodemon -
node:
...
command: nodemon
In my cloudWatch logs I can see everything start -
14:20:24 npm info lifecycle my_app#1.0.0~start: my_app#1.0.0
Then I see the health check requests (all with http 200's), then a bit later it all wraps up -
14:23:00 npm info lifecycle mapov_reporting#1.0.0~poststart: mapov_reporting#1.0.0
14:23:00 npm info ok
I've tried wrapping my start.js script in forever-monitor, but that doesn't seem to be making any difference.
UPDATE
My ECS task definition -
{
"requiresAttributes": [
{
"value": null,
"name": "com.amazonaws.ecs.capability.ecr-auth",
"targetId": null,
"targetType": null
},
{
"value": null,
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs",
"targetId": null,
"targetType": null
},
{
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19",
"targetId": null,
"targetType": null
}
],
"taskDefinitionArn": "arn:aws:ecs:us-east-1:562155596068:task-definition/node:12",
"networkMode": "bridge",
"status": "ACTIVE",
"revision": 12,
"taskRoleArn": null,
"containerDefinitions": [
{
"volumesFrom": [],
"memory": 128,
"extraHosts": null,
"dnsServers": null,
"disableNetworking": null,
"dnsSearchDomains": null,
"portMappings": [
{
"hostPort": 0,
"containerPort": 3000,
"protocol": "tcp"
}
],
"hostname": null,
"essential": true,
"entryPoint": null,
"mountPoints": [],
"name": "node",
"ulimits": null,
"dockerSecurityOptions": null,
"environment": [
{
"name": "awslogs-group",
"value": "node_logs"
},
{
"name": "awslogs-region",
"value": "us-east-1"
},
{
"name": "NODE_ENV",
"value": "production"
}
],
"links": null,
"workingDirectory": null,
"readonlyRootFilesystem": null,
"image": "562155596068.dkr.ecr.us-east-1.amazonaws.com/node:06b5a3700df163c8563865c2f23947c2685edd7b",
"command": null,
"user": null,
"dockerLabels": null,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "node_logs",
"awslogs-region": "us-east-1"
}
},
"cpu": 1,
"privileged": null,
"memoryReservation": null
}
],
"placementConstraints": [],
"volumes": [],
"family": "node"
}
Tasks are all stopped with the status Task failed ELB health checks in (target-group .... Health checks pass 2 or 3 times before they start failing. And there's no record of anything other than an http 200 in the logs.
I was using an old version of the mongo driver ~2.0, and keeping connections to more than one db. When I upgraded the driver, the issue went away.
"dependencies": {
"mongodb": ">=2.2"
}
I can only assume that there was a bug in the driver.

CloudFormation how to export a variable

The following is a part of our template. We export a path variable there. However, running from template, this does not work. If I SSH into the server and run the same line, it works and I can use gradle. But just from the template, it somehow doesn't get executed. The other chmod commands work, so the block is clearly execute. Any help is highly appreciated.
...
"LaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"yum": {
"java-1.8.0-openjdk-devel": []
}
},
"sources": {
"/opt": "https://services.gradle.org/distributions/gradle-3.4.1-bin.zip",
"/home/ec2-user": "https://github.com/ABC/XYZ/archive/master.zip"
},
"files": {
"/tmp/gradle_config": {
"content": {
"Fn::Join": ["",
[
"#!/bin/bash -ex\n",
"chmod -R 755 gradle-3.4.1/\n",
"export PATH=$PATH:/opt/gradle-3.4.1/bin\n" //<<<< This does not work
]
]
},
"mode": "000500",
"owner": "root",
"group": "root"
},
"/tmp/app_config": {
"content": {
"Fn::Join": ["",
[
"#!/bin/bash -ex\n",
"chmod -R 777 XYZ-master/\n"
]
]
},
"mode": "000500",
"owner": "root",
"group": "root"
}
},
"commands": {
"01_config": {
"command": "/tmp/gradle_config",
"cwd" : "/opt"
},
"02_config": {
"command": "/tmp/app_config",
"cwd" : "/home/ec2-user"
}
}
}
}
}, ...
I found the solution. All those lines are executed as root user. The export PATH... therefore wasn't for my ec2-user. The way I handled is was by putting the path variable (globally) into the /etc/environment file.
In my code snippet, just replace
"export PATH=$PATH:/opt/gradle-3.4.1/bin\n",
with
"echo \"PATH=$PATH:/opt/gradle-3.4.1/bin\" >> /etc/environment"",

Can't run docker container on Marathon with network HOST?

I am trying to run some cassandra instances (docker containers) on marathon.
This following description works well:
{
"id": "cassandra",
"constraints": [["hostname", "CLUSTER", "docker-sl-vm"]],
"container": {
"type": "DOCKER",
"docker": {
"image": "cassandra:latest",
"network": "BRIDGE",
"portMappings": [ {"containerPort": 9042,"hostPort": 0,"servicePort": 9042,"protocol": "tcp"} ]
}
},
"env": {
"CASSANDRA_SEED_COUNT": "1"
},
"cpus": 0.5,
"mem": 512.0,
"instances": 1,
"backoffSeconds": 1,
"backoffFactor": 1.15,
"maxLaunchDelaySeconds": 3600
}
However, I was following a tutorial that uses the following description:
{
"id": "cassandra-seed",
"constraints": [
[
"hostname",
"UNIQUE"
]
],
"ports": [
7199,
7000,
7001,
9160,
9042
],
"requirePorts": true,
"container": {
"type": "DOCKER",
"docker": {
"image": "cassandra:latest",
"network": "HOST",
"privileged": true
}
},
"env": {
"CASSANDRA_SEED_COUNT": "1"
},
"cpus": 0.5,
"mem": 512,
"instances": 2,
"backoffSeconds": 1,
"backoffFactor": 1.15,
"maxLaunchDelaySeconds": 3600,
"healthChecks": [
{
"protocol": "TCP",
"gracePeriodSeconds": 30,
"intervalSeconds": 30,
"portIndex": 4,
"timeoutSeconds": 60,
"maxConsecutiveFailures": 30
}
],
"upgradeStrategy": {
"minimumHealthCapacity": 0.5,
"maximumOverCapacity": 0.2
}
}
PROBLEM
If I try ot use the second Marathon description, It takes forever and never loads. It just gets stuck on deploying and do not give me any error at the DEBUG section.
PS.: I am running the mesos cluster into a VirtualBox Ubuntu trusty Guest.
UPDATE ========================================
I've erased the logs and tried to run it again. The log result is shown below:
Content of mesos-slave.docker-sl-vm.invalid-user.log.INFO.20151110-130520.2713

Resources