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

Error: The URL must be of scheme file #60

Open
cleitonper opened this issue Jun 14, 2021 · 1 comment
Open

Error: The URL must be of scheme file #60

cleitonper opened this issue Jun 14, 2021 · 1 comment

Comments

@cleitonper
Copy link

Error: The URL must be of scheme file

Description

Hi there,

I'm trying to use this action to deploy my project on aws, but I'm getting the following error in Github Action run: Error: The URL must be of scheme file

The stack already exists in CloudFormation, and I'm using the same template file with aws-cloudformation-github-deploy@v1 action, with some parameter overrides.

Looks like the error is related to something that I'm doing wrong with the template parameter.

I'm using the action in this way:

     - name: Deploy to Amazon ECS Cluster
        id: deploy-ecs
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: ${{ env.APP_NAME }}
          template: infra.yml
          no-fail-on-empty-changeset: "1"
          parameter-overrides: >-
            VpcId: ${{ secrets.AWS_VPC }},
            SubnetId: ${{ secrets.AWS_SUBNETS }},
            Image: ${{ steps.push-ecr.outputs.digest }},
            EnvironmentFile: ${{ secrets.ENVIRONMENT_FILE }},
            DatabaseUsername: ${{ secrets.DB_USERNAME }},
            DatabasePassword: ${{ secrets.DB_PASSWORD }},
            DomainName: ${{ env.DOMAIN }}

The complete workflow file can be viewed below

Aditional Information

CloudFormation template
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VpcId:
  Type: AWS::EC2::VPC::Id
  Description: Select a VPC that allows instances to access the Internet.
SubnetId:
  Type: List<AWS::EC2::Subnet::Id>
  Description: Select at two subnets in your selected VPC.
DomainName:
  Type: String
  Description: >
    The Fully Qualified Domain Name (FQDN) to request a SSL/TLS Certificate.
    You can use a wildcard (*) to request a certificate for many subdomanins.
    For example: *.webapp.com will request a certificate for www.webapp.com
    and api.webapp.com and so on.
DesiredCapacity:
  Type: Number
  Default: "1"
  Description: Number of instances to launch in your ECS cluster.
MaxSize:
  Type: Number
  Default: "2"
  Description: Maximum number of instances that can be launched in your ECS cluster.
EnvironmentFile:
  Type: String
  Description: The Amazon Resource Name (ARN) of an .env file stored in a s3 bucket.
InstanceType:
  Type: String
  Description: EC2 instance type
  Default: t2.micro
  AllowedValues:
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    - m3.medium
    - m3.large
    - m3.xlarge
    - m3.2xlarge
    - m4.large
    - m4.xlarge
    - m4.2xlarge
    - m4.4xlarge
    - m4.10xlarge
    - c4.large
    - c4.xlarge
    - c4.2xlarge
    - c4.4xlarge
    - c4.8xlarge
    - c3.large
    - c3.xlarge
    - c3.2xlarge
    - c3.4xlarge
    - c3.8xlarge
    - r3.large
    - r3.xlarge
    - r3.2xlarge
    - r3.4xlarge
    - r3.8xlarge
    - i2.xlarge
    - i2.2xlarge
    - i2.4xlarge
    - i2.8xlarge
  ConstraintDescription: Please choose a valid instance type.
DatabaseUsername:
  Type: String
  Description: Type a login ID for the master user of your DB instance.
DatabasePassword:
  NoEcho: true
  Type: String
  Description: Type a password for the master user of your DB instance.
DatabaseType:
  Type: String
  Description: Choose a DB instance class.
  Default: db.t2.micro
  AllowedValues:
    - db.t2.micro
    - db.t2.small
    - db.t2.medium
    - db.t2.large
    - db.t2.xlarge
    - db.t2.2xlarge
    - db.t3.micro
    - db.t3.small
    - db.t3.medium
    - db.t3.large
    - db.t3.xlarge
    - db.t3.2xlarge
  ConstraintDescription: Please choose a valid instance type.
Image:
  Type: String
  Description: The image containing the application.
Mappings:
AWSRegionToAMI:
  us-east-1:
    AMIID: ami-01146a2120f5af1c5
  us-east-2:
    AMIID: ami-05f074075b6f667c0
  us-west-1:
    AMIID: ami-08850e7f1d87d3e1c
  us-west-2:
    AMIID: ami-063ffacdfca60f249
  sa-east-1:
    AMIID: ami-08d8d510618560f82
Resources:
Cluster:
  Type: AWS::ECS::Cluster
  Properties:
    ClusterName: !Ref AWS::StackName
SecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    VpcId: !Ref VpcId
    GroupName: !Ref AWS::StackName
    GroupDescription: !Join [ "", [ !Ref AWS::StackName, " ", "security group" ] ]
    SecurityGroupIngress:
      - Description: HTTP IPv4
        IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
      - Description: HTTP IPv6
        IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIpv6: ::/0
      - Description: HTTPS IPv4
        IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIp: 0.0.0.0/0
      - Description: HTTPS IPv6
        IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIpv6: ::/0
SecurityGroupPostgresInbound:
  Type: AWS::EC2::SecurityGroupIngress
  Properties:
    Description: PostgreSQL internal traffic
    GroupId: !Ref SecurityGroup
    SourceSecurityGroupId: !Ref SecurityGroup
    IpProtocol: tcp
    FromPort: 5432
    ToPort: 5432
SecurityGroup4000Inbound:
  Type: AWS::EC2::SecurityGroupIngress
  Properties:
    Description: TCP internal traffic for healthchecks
    GroupId: !Ref SecurityGroup
    SourceSecurityGroupId: !Ref SecurityGroup
    IpProtocol: tcp
    FromPort: 4000
    ToPort: 4000
LogGroup:
  Type: AWS::Logs::LogGroup
  Properties:
    RetentionInDays: 7
    LogGroupName: !Ref AWS::StackName
TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    NetworkMode: awsvpc
    ExecutionRoleArn: !GetAtt TaskExecutionRole.Arn
    RequiresCompatibilities:
      - EC2
    ContainerDefinitions:
      - Name: !Ref AWS::StackName
        Image: !Ref Image
        Essential: true
        MemoryReservation: 128
        EnvironmentFiles:
          - Type: s3
            Value: !Ref EnvironmentFile
        PortMappings:
          - ContainerPort: 4000
            HostPort: 4000
        LogConfiguration:
          LogDriver: awslogs
          Options:
            awslogs-group: !Ref LogGroup
            awslogs-region: !Ref AWS::Region
            awslogs-stream-prefix: !Ref AWS::StackName
LoadBalancer:
  Type: AWS::ElasticLoadBalancingV2::LoadBalancer
  Properties:
    Type: application
    Name: !Ref AWS::StackName
    Scheme: internet-facing
    Subnets: !Ref SubnetId
    SecurityGroups: [ !Ref SecurityGroup ]
LoadBalancerHTTPSListener:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    Port: 443
    Protocol: HTTPS
    LoadBalancerArn: !Ref LoadBalancer
    SslPolicy: ELBSecurityPolicy-2016-08
    Certificates:
      - CertificateArn: !Ref Certificate
    DefaultActions:
      - Type: forward
        TargetGroupArn: !Ref TargetGroup
LoadBalancerHTTPListener:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    Port: 80
    Protocol: HTTP
    LoadBalancerArn: !Ref LoadBalancer
    DefaultActions:
      - Type: redirect
        RedirectConfig:
          Protocol: HTTPS
          Host: "#{host}"
          Port: "443"
          Path: /#{path}
          Query: "#{query}"
          StatusCode: HTTP_301
TargetGroup:
  Type: AWS::ElasticLoadBalancingV2::TargetGroup
  DependsOn: LoadBalancer
  Properties:
    Name: !Ref AWS::StackName
    VpcId: !Ref VpcId
    TargetType: ip
    Protocol: HTTP
    Port: 4000
    HealthCheckPath: /api/index.html
    HealthCheckProtocol: HTTP
    HealthCheckPort: '4000'
    HealthyThresholdCount: 2
    HealthCheckIntervalSeconds: 10
    HealthCheckTimeoutSeconds: 5
    UnhealthyThresholdCount: 2
    Matcher:
      HttpCode: 200-399
Certificate:
  Type: AWS::CertificateManager::Certificate
  Properties:
    DomainName: !Ref DomainName
    ValidationMethod: DNS
AutoScalingGroup:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    AutoScalingGroupName: !Ref AWS::StackName
    VPCZoneIdentifier: !Ref SubnetId
    DesiredCapacity: !Ref DesiredCapacity
    MaxSize: !Ref MaxSize
    MinSize: "1"
    LaunchTemplate:
      LaunchTemplateId: !Ref LaunchTemplate
      Version: !GetAtt LaunchTemplate.LatestVersionNumber
  CreationPolicy:
    ResourceSignal:
      Timeout: PT15M
  UpdatePolicy:
    AutoScalingReplacingUpdate:
      WillReplace: true
LaunchTemplate:
  Type: AWS::EC2::LaunchTemplate
  Properties:
    LaunchTemplateName: !Ref AWS::StackName
    LaunchTemplateData:
      InstanceType: !Ref InstanceType
      IamInstanceProfile:
        Arn: !GetAtt EC2InstanceProfile.Arn
      SecurityGroupIds:
        - !Ref SecurityGroup
      ImageId: !FindInMap
        - AWSRegionToAMI
        - !Ref AWS::Region
        - AMIID
      UserData: !Base64
        Fn::Join:
          - ""
          - - |
              #!/bin/bash -xe
            - echo ECS_CLUSTER=
            - !Ref Cluster
            - |2
                >> /etc/ecs/ecs.config
            - |
              yum install -y aws-cfn-bootstrap
            - "/opt/aws/bin/cfn-signal -e $? "
            - "         --stack "
            - !Ref AWS::StackName
            - "         --resource AutoScalingGroup "
            - "         --region "
            - !Ref AWS::Region
            - |+

Service:
  Type: AWS::ECS::Service
  DependsOn:
    - LoadBalancerHTTPListener
    - LoadBalancerHTTPSListener
  Properties:
    ServiceName: !Ref AWS::StackName
    Cluster: !Ref Cluster
    TaskDefinition: !Ref TaskDefinition
    DesiredCount: 1
    LaunchType: EC2
    SchedulingStrategy: REPLICA
    DeploymentController:
      Type: ECS
    DeploymentConfiguration:
      MaximumPercent: 100
      MinimumHealthyPercent: 0
    LoadBalancers:
      - ContainerName: !Ref AWS::StackName
        TargetGroupArn: !Ref TargetGroup
        ContainerPort: 4000
    NetworkConfiguration:
      AwsvpcConfiguration:
        SecurityGroups: [ !Ref SecurityGroup ]
        Subnets: !Ref SubnetId
ServiceScalingTarget:
  Type: AWS::ApplicationAutoScaling::ScalableTarget
  Properties:
    ScalableDimension: ecs:service:DesiredCount
    ServiceNamespace: ecs
    MaxCapacity: 2
    MinCapacity: 1
    RoleARN: !GetAtt AutoscalingRole.Arn
    ResourceId: !Join [ "", [ "service", "/", !Ref Cluster, "/", !GetAtt Service.Name ] ]
ServiceScalingPolicy:
  Type: AWS::ApplicationAutoScaling::ScalingPolicy
  Properties:
    PolicyType: StepScaling
    PolicyName: !Ref AWS::StackName
    ScalingTargetId: !Ref ServiceScalingTarget
    StepScalingPolicyConfiguration:
      AdjustmentType: PercentChangeInCapacity
      MetricAggregationType: Average
      Cooldown: 60
      StepAdjustments:
        - MetricIntervalLowerBound: 0
          ScalingAdjustment: 200
LoadBalancer500sAlarmScaleUp:
  Type: AWS::CloudWatch::Alarm
  Properties:
    Period: 60
    Threshold: 10
    EvaluationPeriods: 1
    Statistic: Average
    AlarmDescription: Alarm if our ALB generates too many HTTP 500s.
    ComparisonOperator: GreaterThanThreshold
    MetricName: HTTPCode_ELB_5XX_Count
    Namespace: !Join [ "", [ "aws", "/", !Ref AWS::StackName ] ]
    Dimensions:
      - Name: LoadBalancer
        Value: !GetAtt LoadBalancer.LoadBalancerFullName
    AlarmActions:
      - !Ref ServiceScalingPolicy
EC2Role:
  Type: AWS::IAM::Role
  Properties:
    Path: /
    AssumeRolePolicyDocument:
      Statement:
        - Effect: Allow
          Action:
            - "sts:AssumeRole"
          Principal:
            Service:
              - ec2.amazonaws.com
    Policies:
      - PolicyName: !Join [ "", [ !Ref AWS::StackName, "-ec2-role" ] ]
        PolicyDocument:
          Statement:
            - Effect: Allow
              Resource: "*"
              Action:
                - "ecs:CreateCluster"
                - "ecs:DeregisterContainerInstance"
                - "ecs:DiscoverPollEndpoint"
                - "ecs:Poll"
                - "ecs:RegisterContainerInstance"
                - "ecs:StartTelemetrySession"
                - "ecs:Submit*"
                - "logs:CreateLogStream"
                - "logs:PutLogEvents"
AutoscalingRole:
  Type: AWS::IAM::Role
  Properties:
    Path: /
    AssumeRolePolicyDocument:
      Statement:
        - Effect: Allow
          Action:
            - "sts:AssumeRole"
          Principal:
            Service:
              - application-autoscaling.amazonaws.com
    Policies:
      - PolicyName: !Join [ "", [ !Ref AWS::StackName, "-autoscaling-role" ] ]
        PolicyDocument:
          Statement:
            - Effect: Allow
              Resource: "*"
              Action:
                - "application-autoscaling:*"
                - "cloudwatch:DescribeAlarms"
                - "cloudwatch:PutMetricAlarm"
                - "ecs:DescribeServices"
                - "ecs:UpdateService"
EC2InstanceProfile:
  Type: AWS::IAM::InstanceProfile
  Properties:
    Path: /
    Roles:
      - !Ref EC2Role
TaskExecutionRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - sts:AssumeRole
          Principal:
            Service: ecs-tasks.amazonaws.com
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      - arn:aws:iam::aws:policy/AmazonS3FullAccess
Database:
  Type: AWS::RDS::DBInstance
  Properties:
    DBName: !Ref AWS::StackName
    DBInstanceIdentifier: !Ref AWS::StackName
    DBInstanceClass: !Ref DatabaseType
    MasterUsername: !Ref DatabaseUsername
    MasterUserPassword: !Ref DatabasePassword
    VPCSecurityGroups: [ !Ref SecurityGroup ]
    PubliclyAccessible: false
    EnablePerformanceInsights: false
    BackupRetentionPeriod: 0
    Engine: Postgres
    EngineVersion: '12.5'
    AllocatedStorage: '20'
    StorageType: gp2
    MultiAZ: false
Outputs:
Service:
  Value: !Ref Service
Cluster:
  Value: !Ref Cluster
LoadBalancer:
  Description: LoadBalancer URL
  Value: !GetAtt LoadBalancer.DNSName
TaskDefinition:
  Value: !Ref TaskDefinition
Workflow file
name: Deploy to Amazon ECS

on:
workflow_dispatch:
  inputs:
    version:
      description: Version to deploy
      default: 'latest'
      required: true

env:
AWS_REGION: us-east-1
APP_NAME: rocketpay
DOMAIN: '*.rocketpay.tk'

defaults:
run:
  shell: bash

jobs:
deploy:
  name: Deploy
  runs-on: ubuntu-latest
  environment: deployment
  permissions:
    packages: write
    contents: read

  steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Set up Docker Buildx
      id: buildx
      uses: docker/setup-buildx-action@v1

    - name: Cache Docker layers
      uses: actions/cache@v2
      with:
        path: /tmp/.buildx-cache
        key: ${{ runner.os }}-buildx-${{ github.sha }}
        restore-keys: ${{ runner.os }}-buildx-

    - name: Build, tag, and push image to Amazon ECR
      id: push-ecr
      uses: docker/build-push-action@v2
      with:
        target: production
        cache-from: type=local,src=/tmp/.buildx-cache
        cache-to: type=local,dest=/tmp/.buildx-cache
        tags: |
          ${{ steps.login-ecr.outputs.registry }}/${{ env.APP_NAME }}:latest
          ${{ steps.login-ecr.outputs.registry }}/${{ env.APP_NAME }}:${{ github.event.inputs.version }}

    - name: Deploy to Amazon ECS Cluster
      id: deploy-ecs
      uses: aws-actions/aws-cloudformation-github-deploy@v1
      with:
        name: ${{ env.APP_NAME }}
        template: infra.yml
        no-fail-on-empty-changeset: "1"
        parameter-overrides: >-
          VpcId: ${{ secrets.AWS_VPC }},
          SubnetId: ${{ secrets.AWS_SUBNETS }},
          Image: ${{ steps.push-ecr.outputs.digest }},
          EnvironmentFile: ${{ secrets.ENVIRONMENT_FILE }},
          DatabaseUsername: ${{ secrets.DB_USERNAME }},
          DatabasePassword: ${{ secrets.DB_PASSWORD }},
          DomainName: ${{ env.DOMAIN }}

Screenshot

Click to expand

Screenshot 2021-06-14 at 17-22-02 Build software better, together


Any kind of help is apreciated.
Thanks in advance

@Christopher-R-Perkins
Copy link

Christopher-R-Perkins commented Nov 8, 2024

I understand this is from a few years ago, but I am leaving this comment for those searching in the future.

I had this same issue, what I found was I improperly defined my parameter-overrides. In my case I used : instead of = like @cleitonper did in this issue, which caused the problem. Changing it to = without a space between the key and value and it should work.

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

No branches or pull requests

2 participants