简体   繁体   中英

Deploy CloudFormation Template resulting in error

I want to test the deploy of an ECS stack using AWS CLI from a GitLab pipeline.

My test project's core is a variation of the Docker Compose Flask app .

The file app.py :

import time

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

with its requirements.txt :

flask

The Dockerfile is:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

and the Docker Compose file is:

version: "3.9"
services:
  web:
    image: registry.gitlab.com/<MYNAME>/<MYPROJECT>
    x-aws-pull_credentials: "<CREDENTIALS>"
    ports:
      - "5000:5000"

I generate a CloudFormationTemplate.yml file using an ECS Docker Context (using an ecs Docker Context myecscontext , not the default one) and the command

docker compose convert > CloudFormationTemplate.yml

When I try to deploy on AWS from my local workstation (Win10):

aws cloudformation deploy --template-file CloudFormationTemplate.yml --stack-name test-stack

I get the error

unacceptable character #x0000: special characters are not allowed
  in "<unicode string>", position 3

What's wrong? Thanks.

===========

ADDED

Here the CloudFormationTemplate.yml :

AWSTemplateFormatVersion: 2010-09-09
Resources:
  CloudMap:
    Properties:
      Description: Service Map for Docker Compose project cloudformation
      Name: cloudformation.local
      Vpc: vpc-XXXXXXXX
    Type: AWS::ServiceDiscovery::PrivateDnsNamespace
  Cluster:
    Properties:
      ClusterName: cloudformation
      Tags:
      - Key: com.docker.compose.project
        Value: cloudformation
    Type: AWS::ECS::Cluster
  Default5000Ingress:
    Properties:
      CidrIp: 0.0.0.0/0
      Description: web:5000/tcp on default network
      FromPort: 5000
      GroupId:
        Ref: DefaultNetwork
      IpProtocol: TCP
      ToPort: 5000
    Type: AWS::EC2::SecurityGroupIngress
  DefaultNetwork:
    Properties:
      GroupDescription: cloudformation Security Group for default network
      Tags:
      - Key: com.docker.compose.project
        Value: cloudformation
      - Key: com.docker.compose.network
        Value: default
      VpcId: vpc-XXXXXXXX
    Type: AWS::EC2::SecurityGroup
  DefaultNetworkIngress:
    Properties:
      Description: Allow communication within network default
      GroupId:
        Ref: DefaultNetwork
      IpProtocol: "-1"
      SourceSecurityGroupId:
        Ref: DefaultNetwork
    Type: AWS::EC2::SecurityGroupIngress
  LoadBalancer:
    Properties:
      LoadBalancerAttributes:
      - Key: load_balancing.cross_zone.enabled
        Value: "true"
      Scheme: internet-facing
      Subnets:
      - subnet-XXXXXXXX
      - subnet-XXXXXXXX
      - subnet-XXXXXXXX
      Tags:
      - Key: com.docker.compose.project
        Value: cloudformation
      Type: network
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
  LogGroup:
    Properties:
      LogGroupName: /docker-compose/cloudformation
    Type: AWS::Logs::LogGroup
  WebService:
    DependsOn:
    - WebTCP5000Listener
    Properties:
      Cluster:
        Fn::GetAtt:
        - Cluster
        - Arn
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 100
      DeploymentController:
        Type: ECS
      DesiredCount: 1
      LaunchType: FARGATE
      LoadBalancers:
      - ContainerName: web
        ContainerPort: 5000
        TargetGroupArn:
          Ref: WebTCP5000TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
          - Ref: DefaultNetwork
          Subnets:
          - subnet-XXXXXXXX
          - subnet-XXXXXXXX
          - subnet-XXXXXXXX
      PlatformVersion: 1.4.0
      PropagateTags: SERVICE
      SchedulingStrategy: REPLICA
      ServiceRegistries:
      - RegistryArn:
          Fn::GetAtt:
          - WebServiceDiscoveryEntry
          - Arn
      Tags:
      - Key: com.docker.compose.project
        Value: cloudformation
      - Key: com.docker.compose.service
        Value: web
      TaskDefinition:
        Ref: WebTaskDefinition
    Type: AWS::ECS::Service
  WebServiceDiscoveryEntry:
    Properties:
      Description: '"web" service discovery entry in Cloud Map'
      DnsConfig:
        DnsRecords:
        - TTL: 60
          Type: A
        RoutingPolicy: MULTIVALUE
      HealthCheckCustomConfig:
        FailureThreshold: 1
      Name: web
      NamespaceId:
        Ref: CloudMap
    Type: AWS::ServiceDiscovery::Service
  WebTCP5000Listener:
    Properties:
      DefaultActions:
      - ForwardConfig:
          TargetGroups:
          - TargetGroupArn:
              Ref: WebTCP5000TargetGroup
        Type: forward
      LoadBalancerArn:
        Ref: LoadBalancer
      Port: 5000
      Protocol: TCP
    Type: AWS::ElasticLoadBalancingV2::Listener
  WebTCP5000TargetGroup:
    Properties:
      Port: 5000
      Protocol: TCP
      Tags:
      - Key: com.docker.compose.project
        Value: cloudformation
      TargetType: ip
      VpcId: vpc-XXXXXXXX
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
  WebTaskDefinition:
    Properties:
      ContainerDefinitions:
      - Command:
        - XXXXXXXX.compute.internal
        - cloudformation.local
        Essential: false
        Image: docker/ecs-searchdomain-sidecar:1.0
        LogConfiguration:
          LogDriver: awslogs
          Options:
            awslogs-group:
              Ref: LogGroup
            awslogs-region:
              Ref: AWS::Region
            awslogs-stream-prefix: cloudformation
        Name: Web_ResolvConf_InitContainer
      - DependsOn:
        - Condition: SUCCESS
          ContainerName: Web_ResolvConf_InitContainer
        Essential: true
        Image: registry.gitlab.com/MYUSER/cloudformation
        LinuxParameters: {}
        LogConfiguration:
          LogDriver: awslogs
          Options:
            awslogs-group:
              Ref: LogGroup
            awslogs-region:
              Ref: AWS::Region
            awslogs-stream-prefix: cloudformation
        Name: web
        PortMappings:
        - ContainerPort: 5000
          HostPort: 5000
          Protocol: tcp
        RepositoryCredentials:
          CredentialsParameter: arn:aws:secretsmanager:XXXXXXXXXXXXXXXXXXXXXXXX
      Cpu: "256"
      ExecutionRoleArn:
        Ref: WebTaskExecutionRole
      Family: cloudformation-web
      Memory: "512"
      NetworkMode: awsvpc
      RequiresCompatibilities:
      - FARGATE
    Type: AWS::ECS::TaskDefinition
  WebTaskExecutionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRole
          Condition: {}
          Effect: Allow
          Principal:
            Service: ecs-tasks.amazonaws.com
        Version: 2012-10-17
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - secretsmanager:GetSecretValue
            - ssm:GetParameters
            - kms:Decrypt
            Condition: {}
            Effect: Allow
            Principal: {}
            Resource:
            - arn:aws:secretsmanager:XXXXXXXXXXXXXXXXXXXXXXXX
        PolicyName: webGrantAccessToSecrets
      Tags:
      - Key: com.docker.compose.project
        Value: cloudformation
      - Key: com.docker.compose.service
        Value: web
    Type: AWS::IAM::Role

docker compose convert does not create valid CloudFormation (CFN) template in default context . Before you attempt to generate it, you have to create ECS context:

docker context create ecs myecscontext

Then you have to switch from default context to myecscontext :

docker context use myecscontext

Use docker context ls to confirm that you are in the correct context (ie, myecscontext ). Then you can use your convert command

docker compose convert

to generate actual CFN template.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM