Search code examples
amazon-web-servicesaws-code-deployaws-vpc

AWS CodeDeploy not working in private VPC


I have private Subnet inside VPC, with a routing table as follows:

XX.X.0.X/16 local
0.0.0.0/0 nat-0XXXXXXXXX

With above configuration AWS CodeDeploy fails with error as Error code: HEALTH_CONSTRAINTS with no log entry in /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log.

But when I change it to allow public access by adding Internet Gateway with following routing table AWS CodeDeploy gets successfully compeleted.

XX.X.0.X/16 local   
0.0.0.0/0 igw-0XXXXXXXXX

Am I missing any other configuration?


Solution

  • The CodeDeploy agent requires outbound access to the internet for access to 4 different service endpoints. Access to all these endpoints are required in order for the service to work properly.

    Outbound access to the internet is needed to access to (1) the CodeDeploy service endpoints, and (2) to access S3 or Github services - this access is required to the agent to download software deployment package for the revision being deployed.

    From CodeDeploy FAQs:

    ...AWS CodeDeploy agent installed on the Amazon EC2 instances must be able to access the public AWS CodeDeploy and Amazon S3 service endpoints. For more information, see AWS CodeDeploy Endpoints and Amazon S3 Endpoints.

    (3) The CodeDeploy agent will regularly check for software updates, and automatically update itself within 24 hours of a new release. A properly configured CodeDeploy agent instance will allow IAM S3 access to the AWS CodeDeploy Resource Kit Reference bucket, so that it can access new software when available. Failure to provide update access here could break your implementation when the service is upgraded, or limit access to new features.

    (4) Regarding CodeDeploy command and control, the source code for the agent shows a reference to a special command https endpoint, called the AWS_DEPLOY_CONTROL_ENDPOINT:

    From aws-codedeploy-agent software repository, the deploy_control_endpoint.rb file has the following:

    require 'aws-sdk-core'
    
    module Aws
      module Plugins
        class DeployControlEndpoint < Seahorse::Client::Plugin
          option(:endpoint) do |cfg|
            url = ENV['AWS_DEPLOY_CONTROL_ENDPOINT']
            if url.nil?
              url = "https://codedeploy-commands.#{cfg.region}.amazonaws.com"
              if "cn" == cfg.region.split("-")[0]
                url.concat(".cn")
              end
            end
            url
          end
        end
      end
    end
    

    While apparently not documented, access to this endpoint is also required.