Git Product home page Git Product logo

aws-account-registration-plugin-spinnaker's Introduction

Spinnaker Plugin for Dynamic Account Registration

Build

This plugin queries a remote endpoint for AWS account information in JSON format. Accounts are added and/or removed without restarting clouddriver service.

What this plugin does

  1. Periodically syncs with a configured remote host to update Spinnaker AWS and ECS accounts. Supports account addition, removal, and update.
  2. On-demand account loading. If a AWS account is not found in the local repository at the time of pipeline execution, the plugin will perform a sync with remote host to provide needed account (if found in remote host).
  3. Supports IAM authentication when used with API Gateway. The Spinnaker managing account role must have the permission to invoke configured API gateway.

Requirements

  1. Must be used with Spinnaker version 1.28 or higher.
  2. Must enable AWS support
  3. Must enable Lambda support.
  4. Must enable ECS support
  5. Must have a HTTP endpoint which provides JSON payload when invoked with GET (Example available at .github/integration-testing/mock-server/)

Expected JSON payload

This plugin expects the following JSON payload from the configured remote host, configured with the url property.

{
  "SpinnakerAccounts": [
    {
      "AccountId": "12345678901",
      "SpinnakerAccountName": "test-3",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE | SUSPENDED",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ecs", "lambda", "ec2"
      ],
      "UpdatedAt": "2020-08-27T16:52:59.026696+00:00"
    }
  ],
  "Pagination": {
    "NextUrl": "http://some/next/url"
  }
}

Note

  1. Plugin performs GET with query string field UpdatedAt.gt=<TIME> after the initial sync. Expectation is that the remote host will return accounts that were updated after the specified time by the field. This is done to avoid returning and processing all accounts every time sync occurs.
  2. The UpdatedAt.gt field value is determined using the most recent time value provided in the UpdatedAt JSON field. E.g. if two accounts were retruned with timestamps 2020-08-27T16:52:59.026696+00:00 and 2030-12-27T16:52:59.026696+00:00, next request will have a query string field UpdatedAt.gt=2030-12-27T16:52:59.026696+00:00.
  3. The SpinnakerProviders JSON field means the following:
    • If empty, AWS and ECS accounts are removed.
    • If only ec2 is specified, Spinnaker AWS account is created.
    • If only lambda is specified, Spinnaker AWS account with Lambda support is created.
    • If ecs is specified, Spinnaker AWS and ECS accounts are created.
  4. ECS accounts are named with corresponding AWS account's name with "-ecs" suffix. E.g. ECS account is named account1-ecs if its corresponding AWS account name is account1
  5. If the SpinnakerProviders field is set to SUSPENDED, AWS and ECS accounts are removed.
  6. If the NextUrl field is present, plugin will perform a GET request against the URL specified by the field. Returned accounts are aggregated, then processed.
  7. Failure paths are available here:

Usage

  1. Add the following to clouddriver.yml in the necessary profile to load plugin.
spinnaker:
    extensibility:
      plugins:
        AWS.AccountRegistration:
          id: AWS.AccountRegistration
          enabled: true
          version: <<plugin release version>>
          extensions: {}
      repositories:
        awsAccountRegistrationPluginRepo:
          id: awsAccountRegistrationPluginRepo
          url: https://raw.githubusercontent.com/spinnaker-plugins/aws-account-registration-plugin-spinnaker/master/plugins.json

accountProvision:
  url: 'http://localhost:8080' # Remote host address. Query string is supported but must not include space characters.
  iamAuth: false # Enable IAM authentication for API Gateway.
  iamAuthRegion: 'us-west-2' # Specify which region API Gateway is deployed. Required if `iamAuth` is enabled.
  connectionTimeout: 2000 # How long to wait before initial connection timeouts
  readTimeout: 6000 # How long to wait for remote server to return results.
  maxBackoffTime: 3600000 # How long, in milli seconds, maximum backoff time should be.

credentials:
  poller:
    enabled: true
    types:
        aws:
          reloadFrequencyMs: 20000 # Specify how often in milliseconds credentials should be synced.
        ecs:
          reloadFrequencyMs: 20000 # Specify how often in milliseconds credentials should be synced.

Manually Build and Load Plugin

  1. Run ./gradlew releaseBundle in the root of this project.
  2. The above command will create a zip file, build/distributions/spinnaker-aws-account-registration*.zip.
  3. Copy the zip file to Clouddriver plugin directory. Defaults to /opt/clouddriver/plugins. This directory can be specified by the plugins-root-path configuration property.
  4. Enable the plugin by placing the following in Clouddriver profile
spinnaker:
  extensibility:
    plugins-root-path: /opt/clouddriver/plugins # Specify plugin directory if necessary.
    plugins:
      AWS.AccountRegistration:
        enabled: true
    repositories: {}
    strict-plugin-loading: false
# Available Plugin configuration properties:
accountProvision:
  url: 'http://localhost:8080' # Remote host address. Query string is supported but must not include space characters.
  iamAuth: false # Enable IAM authentication for API Gateway.
  iamAuthRegion: 'us-west-2' # Specify which region API Gateway is deployed. Required if `iamAuth` is enabled.
  connectionTimeout: 2000 # How long to wait before initial connection timeouts
  readTimeout: 6000 # How long to wait for remote server to return results.
  maxBackoffTime: 3600000 # How long, in milli seconds, maximum backoff time should be.
  
credentials:
  poller:
    enabled: true
    types:
        aws:
          reloadFrequencyMs: 20000 # Specify how often in milliseconds credentials should be synced.
        ecs:
          reloadFrequencyMs: 20000 # Specify how often in milliseconds credentials should be synced.

Developer guide

Developer guide for this plugin is available here:

Security

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

aws-account-registration-plugin-spinnaker's People

Contributors

amazon-auto avatar github-actions[bot] avatar ichi0915 avatar nabuskey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-account-registration-plugin-spinnaker's Issues

Test Suspension for All Spinnaker Accounts - EC2, ECS, Lambda

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 26 August 2020
Title of Test: Test Suspension for All Spinnaker Accounts - EC2, ECS, Lambda

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Create Spinnaker Account for EC2, ECS, and Lambda by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account creation

Expected:

Two accounts are created - one with type: aws and another with type: ecs

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  },
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  }
]

Step 3

Suspend all Spinnaker accounts by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "SUSPENDED",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 4

Execute curl http://localhost:7002/credentials to verify account removal

Expected

There will be no accounts listed

Output
[
]

Test Lambda Function Deployment via Deck UI

Name of Tester: Manabu McCloskey
Date of Test: 08/26/2020
Title of Test: Test Lambda Function Deployment via Deck UI

Spinnaker Version: 1.22
Plugin Version: 0.0.1

Status: PASS

Step 1

Enable Lambda function page in UI
Create a function in the newly provisioned account using the UI.

Expected:

Lambda function is created without any errors.

Output:

Lambda function is created without any errors.

Test Partial Activation for Spinnaker Accounts - EC2

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 25 August 2020
Title of Test: Test Partial Activation for Spinnaker Accounts - EC2

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Create Spinnaker Account for EC2, ECS, and Lambda by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account creation

Expected:

Two accounts are created - one with type: aws and another with type: ecs

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

Step 3

Edit Spinnaker Account and remove all Spinnaker accounts by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [

      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 4

Execute curl http://localhost:7002/credentials to verify account removal

Expected

There will be no accounts listed

Output
[
]

Step 5

Edit Spinnaker Account to create an EC2 Spinnaker account by editing the response.json file with the below content to be served via the Golang test server

Step 6

Execute curl http://localhost:7002/credentials to verify account creation

Expected

There will be a single account with type: aws

Output
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  }
]

Test Activation for All Spinnaker Accounts - EC2, ECS & Lambda

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 26 August 2020
Title of Test: Test Activation for All Spinnaker Accounts - EC2, ECS & Lambda
Test Case: 1

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Create Spinnaker Account for EC2, ECS, and Lambda by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account creation

Expected:

Two accounts are created - one with type: aws and another with type: ecs

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  },
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  }
]

Test Partial Suspension for Spinnaker Accounts - ECS & Lambda

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 25 August 2020
Title of Test: Test Partial Suspension for Spinnaker Accounts - ECS & Lambda

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: FAIL

Step 1:

Create Spinnaker Account for EC2, ECS, and Lambda by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ecs", "lambda", "ec2"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909979587",
      "UpdatedAt": "1598027546352337694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2:

run curl http://localhost:7002/credentials to verify account creation

Expected:

Account is created with ECS and EC2 enabled

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

Step 3:

Edit Spinnaker Account to only support EC2 by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 4:

run curl http://localhost:7002/credentials to verify account deactivation

Expected:

ECS account credentials is removed

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

Activate and Suspend Spinnaker Account - EC2, ECS, Lambda - Production Instance

Name of Tester: Hitesh Parikh
Date of Test: 08/24/2020
Title of Test: Activate and then suspend Spinnaker Account with EC2, ECS, Lambda in Production Instance.

Step 1: Create a PRODUCTION account. Copy Alfred mock API response JSON in response.json in the directory where 'response' go server runs.

Alfred mock API response JSON:

`{
"Accounts": [
{
"AccountId": "111122223333",
"Regions": [
"us-east-1"
],
"SpinnakerAccountName": "hitesh-2-ec2-111122223333",
"SpinnakerAssumeRole": "role/spinnakerManaged",
"SpinnakerId": "PRODUCTION",
"SpinnakerProviders": [
"ecs",
"lambda",
"ec2"
],
"SpinnakerStatus": "ACTIVE",
"CreatedAt": "1598026448909979587",
"UpdatedAt": "1598027546352337694"
}
],
"Pagination": {

"NextUrl": ""

}
}`

Step 2: curl http://localhost:7002/credentials

Result: Spinnaker account 'hitesh-2-ec2-111122223333' created with provider types - "ecs" and "aws".

Spinnaker 'credentials' Response JSON:

[ { "accountId": "111122223333", "accountType": "ecs", "challengeDestructiveActions": false, "cloudProvider": "ecs", "environment": "hitesh-1-ec2-111122223333", "name": "hitesh-1-ec2-111122223333-ecs", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "ecs" }, { "accountId": "111122223333", "accountType": "hitepari-aws-account", "challengeDestructiveActions": false, "cloudProvider": "aws", "environment": "hitepari-aws-account", "name": "hitepari-aws-account", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "aws" }, { "accountId": "111122223333", "accountType": "hitesh-2-ec2-111122223333", "challengeDestructiveActions": false, "cloudProvider": "aws", "environment": "hitesh-2-ec2-111122223333", "name": "hitesh-2-ec2-111122223333", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "aws" }, { "accountId": "111122223333", "accountType": "ecs", "challengeDestructiveActions": false, "cloudProvider": "ecs", "environment": "hitesh-2-ec2-111122223333", "name": "hitesh-2-ec2-111122223333-ecs", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "ecs" }, { "accountId": "111122223333", "accountType": "ecs", "challengeDestructiveActions": false, "cloudProvider": "ecs", "environment": "hitepari-aws-account", "name": "ecs-account-name", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "ecs" }, { "accountId": "111122223333", "accountType": "hitesh-1-ec2-111122223333", "challengeDestructiveActions": false, "cloudProvider": "aws", "environment": "hitesh-1-ec2-111122223333", "name": "hitesh-1-ec2-111122223333", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "aws" } ]
Step 3: Account suspended in Alfred. Copy Alfred mock API response JSON in response.json in the directory where 'response' go server runs.

Alfred mock API response JSON:
{ "Accounts": [ { "AccountId": "111122223333", "Regions": [ "us-east-1" ], "SpinnakerAccountName": "hitesh-2-ec2-111122223333", "SpinnakerAssumeRole": "role/spinnakerManaged", "SpinnakerId": "PRODUCTION", "SpinnakerProviders": [ ], "SpinnakerStatus": "SUSPENDED", "CreatedAt": "1598027546352337694", "UpdatedAt": "1598027546352337694" } ], "Pagination": { "NextUrl": "" } }

Step 4: Verify that suspended account is deleted. curl http://localhost:7002/credentials

Result: Spinnaker account 'hitesh-2-ec2-111122223333' is deleted from spinnaker credentials.

Spinnaker 'credentials' Response JSON:
[ { "accountId": "111122223333", "accountType": "hitepari-aws-account", "challengeDestructiveActions": false, "cloudProvider": "aws", "environment": "hitepari-aws-account", "name": "hitepari-aws-account", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "aws" }, { "accountId": "111122223333", "accountType": "ecs", "challengeDestructiveActions": false, "cloudProvider": "ecs", "environment": "hitepari-aws-account", "name": "ecs-account-name", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "ecs" } ]

Test Multiple Activations for Same Spinnaker Accounts - EC2, ECS, Lambda

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 25 August 2020
Title of Test: Test Multiple Activations for Same Spinnaker Accounts - EC2, ECS, Lambda

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Create Spinnaker Account for EC2, ECS, and Lambda by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account creation

Expected:

Two accounts are created - one with type: aws and another with type: ecs

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

Step 3

Update the Spinnaker accounts with the same active accounts by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 4

Execute curl http://localhost:7002/credentials to verify accounts

Expected:

Two accounts are shown - one with type: aws and another with type: ecs - and no errors are thrown

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
   {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

Activate Spinnaker Account - EC2, ECS, Lambda - Sandbox Instance

Name of Tester: Hitesh Parikh
Date of Test: 08/24/2020
Title of Test: Activate Spinnaker Account with EC2, ECS, Lambda in Sandbox Instance.

Step 1: Copy Alfred mock API response JSON in response.json in the directory where 'response' go server runs.

Alfred mock API response JSON:

{ "Accounts": [ { "AccountId": "569729057445", "SpinnakerAccountName": "hitesh-1-ec2-569729057445", "Regions": [ "us-east-1" ], "SpinnakerStatus": "ACTIVE", "SpinnakerAssumeRole": "role/spinnakerManaged", "SpinnakerProviders": [ "ecs", "lambda", "ec2" ], "SpinnakerId": "SANDBOX", "CreatedAt": "1598026448909979587", "UpdatedAt": "1598027546352337694" } ], "Pagination": { "NextUrl": "" } }

Step 2: curl http://localhost:7002/credentials

Result: Spinnaker account 'hitesh-1-ec2-569729057445' created with provider types - "ecs" and "aws".

Spinnaker 'credentials' Response JSON:

[ { "accountId": "569729057445", "accountType": "ecs", "challengeDestructiveActions": false, "cloudProvider": "ecs", "environment": "hitesh-1-ec2-569729057445", "name": "hitesh-1-ec2-569729057445-ecs", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "ecs" }, { "accountId": "569729057445", "accountType": "hitesh-1-ec2-569729057445", "challengeDestructiveActions": false, "cloudProvider": "aws", "environment": "hitesh-1-ec2-569729057445", "name": "hitesh-1-ec2-569729057445", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "aws" }, { "accountId": "569729057445", "accountType": "ecs", "challengeDestructiveActions": false, "cloudProvider": "ecs", "environment": "hitepari-aws-account", "name": "ecs-account-name", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "ecs" }, { "accountId": "569729057445", "accountType": "hitepari-aws-account", "challengeDestructiveActions": false, "cloudProvider": "aws", "environment": "hitepari-aws-account", "name": "hitepari-aws-account", "permissions": {}, "primaryAccount": false, "requiredGroupMembership": [], "type": "aws" } ]

Test Incremental Activation for Spinnaker Accounts - EC2

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 25 August 2020
Title of Test: Test Incremental Activation for Spinnaker Accounts - EC2

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Create Spinnaker Account for EC2 by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account creation

Expected:

There will be a single account with type: aws

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  }
]

Step 3

Edit Spinnaker Account and add an ECS Spinnaker accounts by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 4

Execute curl http://localhost:7002/credentials to verify account creation

Expected

Two accounts are created - one with type: aws and another with type: ecs

Output
[
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  },
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  }
]

Test Suspension of Non-Existent Spinnaker Account

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 25 August 2020
Title of Test: Test Suspension of Non-Existent Spinnaker Account

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Suspend non-existent Spinnaker accounts by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "SUSPEND",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [

      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account suspension

Expected:

There will neither accounts listed nor errors thrown

Output:
[
]

Test Multiple Suspensions for Same Spinnaker Accounts - EC2, ECS, Lambda

Name of Tester: Jason Coffman (@jasoncoffman)
Date of Test: 25 August 2020
Title of Test: Test Multiple Suspensions for Same Spinnaker Accounts - EC2, ECS, Lambda

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

Create Spinnaker Account for EC2, ECS, and Lambda by creating a response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Execute curl http://localhost:7002/credentials to verify account creation

Expected:

Two accounts are created - one with type: aws and another with type: ecs

Output:
[
  {
    "accountId": "111122223333",
    "accountType": "isengard-2",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "isengard-2",
    "name": "isengard-2",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
  {
    "accountId": "111122223333",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "isengard-2",
    "name": "isengard-2-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

Step 3

Suspend Spinnaker Account for EC2, ECS, and Lambda by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "SUSPENDED",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 4

Execute curl http://localhost:7002/credentials to verify account suspension

Expected

There will be no accounts listed

Output
[
]

Step 5

Update the Spinnaker accounts with the same suspended accounts by editing the response.json file with the below content to be served via the Golang test server

{
  "SpinnakerAccounts": [
    {
      "AccountId": "111122223333",
      "SpinnakerAccountName": "isengard-2",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "SUSPENDED",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ec2", "ecs", "lambda"
      ],
      "SpinnakerId": "spinnaker1",
      "CreatedAt": "1598026448909989587",
      "UpdatedAt": "1598027546352397694"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 6

Execute curl http://localhost:7002/credentials to verify account suspension

Expected

There will neither accounts listed nor errors thrown

Output
[
]

Test deployment from Deck for non-existent account

Name of Tester: Manabu McCloskey
Date of Test: 08/26/2020
Title of Test: Test deployment from Deck for non-existent account

Spinnaker Version: 1.22
Plugin Version: 0.0.1

Status: PASS

Step 1

Create an account in "SUSPENDED" state.
Set pullFrequencyInMilliSeconds to 10000000.
Attempt to deploy to the account that does not exist.

{
  "clusters": [
    {
      "account": "mccloman-3-ecs",
      "application": "test",
      "associatePublicIpAddress": false,
      "availabilityZones": {
        "us-west-2": [
          "us-west-2a",
          "us-west-2b",
          "us-west-2c",
          "us-west-2d"
        ]
      },
      "capacity": {
        "desired": 1,
        "max": 1,
        "min": 1
      },
      "cloudProvider": "ecs",
      "computeUnits": 256,
      "copySourceScalingPoliciesAndActions": false,
      "dockerImageCredentialsSecret": "None (No registry credentials)",
      "dockerLabels": {},
      "ecsClusterName": "mccloman-3-test",
      "environmentVariables": {},
      "freeFormDetails": "e",
      "healthCheckGracePeriodSeconds": "",
      "healthCheckType": "EC2",
      "iamRole": "None (No IAM role)",
      "imageDescription": {
        "account": "my-ecr-registry",
        "fromTrigger": true,
        "imageId": "index.docker.io/nabuskey/public-test:echo",
        "registry": "index.docker.io",
        "repository": "nabuskey/public-test",
        "tag": "echo"
      },
      "launchType": "FARGATE",
      "loadBalancers": [],
      "moniker": {
        "app": "test",
        "detail": "e",
        "stack": "t"
      },
      "networkMode": "awsvpc",
      "placementConstraints": [],
      "placementStrategyName": "",
      "placementStrategySequence": [],
      "preferSourceCapacity": false,
      "provider": "ecs",
      "reservedMemory": 512,
      "securityGroupNames": [
        "no-ingress-sg"
      ],
      "securityGroups": [],
      "serviceDiscoveryAssociations": [],
      "stack": "t",
      "strategy": "",
      "subnetType": "private-subnet1",
      "tags": {},
      "targetGroup": "",
      "targetGroupMappings": [],
      "taskDefinitionArtifact": {},
      "useSourceCapacity": false,
      "useTaskDefinitionArtifact": false
    }
  ],
  "name": "Deploy",
  "type": "deploy"
}
Expected:

Deployment fails.

Output:
Exception ( Create Server Group )
credentials not found (name: mccloman-3-ecs, names: [my-ecr-registry, mccloman-1-ecs, mccloman-1])

Step 2

Set account status to ACTIVE
Attempt to deploy to the account.

Expected:

Deployment works.

Output:
{
  "type": "PIPELINE",
  "id": "01EGP2Z7D8Z0BBYR39484SK2S0",
  "application": "test",
  "name": "mccloman3",
  "buildTime": 1598469152230,
  "canceled": false,
  "limitConcurrent": true,
  "keepWaitingPipelines": false,
  "stages": [
    {
      "id": "01EGP2Z7J6HPG11TDVJ7ACZ55Q",
      "refId": "1<1",
      "type": "createServerGroup",
      "name": "Deploy in us-west-2",
      "startTime": 1598469152377,
      "endTime": 1598469223257,
      "status": "SUCCEEDED",
      "context": {
        "healthCheckType": "EC2",
        "placementConstraints": [],
        "deploy.account.name": "mccloman-3-ecs",
        "zeroDesiredCapacityCount": 0,
        "stack": "t",
        "targetGroup": "",
        "lastCapacityCheck": {
          "outOfService": 0,
          "up": 0,
          "failed": 0,
          "starting": 1,
          "down": 0,
          "succeeded": 0,
          "unknown": 0
        },
        "ecsClusterName": "mccloman-3-test",
        "preferSourceCapacity": false,
        "availabilityZones": {
          "us-west-2": [
            "us-west-2a",
            "us-west-2b",
            "us-west-2c",
            "us-west-2d"
          ]
        },
        "source": {},
        "type": "createServerGroup",
        "currentInstanceCount": 1,
        "freeFormDetails": "e",
        "serviceDiscoveryAssociations": [],
        "imageDescription": {
          "registry": "index.docker.io",
          "imageId": "index.docker.io/nabuskey/public-test:echo",
          "fromTrigger": true,
          "tag": "echo",
          "repository": "nabuskey/public-test",
          "account": "my-ecr-registry"
        },
        "kato.last.task.id": {
          "id": "49609896-3f1d-40db-a20b-7af634e9c1c0"
        },
        "targetGroupMappings": [],
        "dockerLabels": {},
        "healthCheckGracePeriodSeconds": "",
        "launchType": "FARGATE",
        "networkMode": "awsvpc",
        "interestingHealthProviderNames": [
          "ecs"
        ],
        "taskDefinitionArtifact": {},
        "kato.task.terminalRetryCount": 0,
        "loadBalancers": [],
        "zones": [],
        "placementStrategySequence": [],
        "tags": {},
        "kato.task.firstNotFoundRetry": -1,
        "capacitySnapshot": {
          "minSize": 1,
          "maxSize": 1,
          "desiredCapacity": 1
        },
        "name": "Deploy in us-west-2",
        "kato.tasks": [
          {
            "resultObjects": [
              {
                "ancestorServerGroupNameByRegion": {
                  "us-west-2": "test-t-e-v003"
                }
              },
              {
                "deployments": [],
                "serverGroupNames": [
                  "us-west-2:test-t-e-v004"
                ],
                "createdArtifacts": [],
                "deployedNamesByLocation": {},
                "deployedNames": [],
                "messages": [],
                "serverGroupNameByRegion": {
                  "us-west-2": "test-t-e-v004"
                }
              }
            ],
            "id": "49609896-3f1d-40db-a20b-7af634e9c1c0",
            "history": [
              {
                "phase": "ORCHESTRATION",
                "status": "Initializing Orchestration Task"
              },
              {
                "phase": "ORCHESTRATION",
                "status": "Processing op: CreateServerGroupAtomicOperation"
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Initializing Create Amazon ECS Server Group Operation..."
              },
              {
                "phase": "ECS_DEPLOY",
                "status": "Found ancestor server group, parsing details (name: test-t-e-v003)"
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Creating Amazon ECS Task Definition..."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Done creating Amazon ECS Task Definition..."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Creating 1 of test-t-e-v004 with arn:aws:ecs:us-west-2::task-definition/test-t-e:10 for mccloman-3-ecs."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Done creating 1 of test-t-e-v004 with arn:aws:ecs:us-west-2::task-definition/test-t-e:10 for mccloman-3-ecs."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Creating Amazon Application Auto Scaling Scalable Target Definition..."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Done creating Amazon Application Auto Scaling Scalable Target Definition."
              },
              {
                "phase": "ORCHESTRATION",
                "status": "Orchestration completed."
              }
            ],
            "status": {
              "retryable": false,
              "completed": true,
              "failed": false
            }
          }
        ],
        "useTaskDefinitionArtifact": false,
        "notification.type": "createdeploy",
        "force.cache.refresh.errors": [],
        "securityGroupNames": [
          "no-ingress-sg"
        ],
        "capacity": {
          "min": 1,
          "desired": 1,
          "max": 1
        },
        "targetDesiredSize": 1,
        "provider": "ecs",
        "cloudProvider": "ecs",
        "kato.result.expected": false,
        "copySourceScalingPoliciesAndActions": false,
        "deploy.server.groups": {
          "us-west-2": [
            "test-t-e-v004"
          ]
        },
        "reservedMemory": 512,
        "processed.server.groups": [],
        "refreshed.server.groups": [],
        "moniker": {
          "app": "test",
          "stack": "t",
          "detail": "e"
        },
        "useSourceCapacity": false,
        "iamRole": "None (No IAM role)",
        "computeUnits": 256,
        "placementStrategyName": "",
        "application": "test",
        "environmentVariables": {},
        "associatePublicIpAddress": false,
        "dockerImageCredentialsSecret": "None (No registry credentials)",
        "securityGroups": [],
        "strategy": "",
        "kato.task.notFoundRetryCount": 0,
        "account": "mccloman-3-ecs",
        "subnetType": "private-subnet1",
        "kato.task.lastStatus": "SUCCEEDED"
      },
      "outputs": {},
      "tasks": [
        {
          "id": "1",
          "implementingClass": "com.netflix.spinnaker.orca.kato.pipeline.strategy.DetermineSourceServerGroupTask",
          "name": "determineSourceServerGroup",
          "startTime": 1598469152451,
          "endTime": 1598469152553,
          "status": "SUCCEEDED",
          "stageStart": true,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "2",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.DetermineHealthProvidersTask",
          "name": "determineHealthProviders",
          "startTime": 1598469152571,
          "endTime": 1598469152739,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "3",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.CreateServerGroupTask",
          "name": "createServerGroup",
          "startTime": 1598469152763,
          "endTime": 1598469153172,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "4",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.MonitorKatoTask",
          "name": "monitorDeploy",
          "startTime": 1598469153188,
          "endTime": 1598469158429,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "5",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ServerGroupCacheForceRefreshTask",
          "name": "forceCacheRefresh",
          "startTime": 1598469158486,
          "endTime": 1598469158601,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "6",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.instance.WaitForUpInstancesTask",
          "name": "waitForUpInstances",
          "startTime": 1598469158656,
          "endTime": 1598469212594,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "7",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ServerGroupCacheForceRefreshTask",
          "name": "forceCacheRefresh",
          "startTime": 1598469212645,
          "endTime": 1598469223039,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "8",
          "implementingClass": "com.netflix.spinnaker.orca.igor.tasks.GetCommitsTask",
          "name": "getCommits",
          "startTime": 1598469223093,
          "endTime": 1598469223200,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": true,
          "loopStart": false,
          "loopEnd": false
        }
      ],
      "syntheticStageOwner": "STAGE_BEFORE",
      "parentStageId": "01EGP2Z7F6W7FS8R5D15DRNBFZ",
      "requisiteStageRefIds": []
    },
    {
      "id": "01EGP2Z7F6W7FS8R5D15DRNBFZ",
      "refId": "1",
      "type": "deploy",
      "name": "Deploy",
      "startTime": 1598469152318,
      "endTime": 1598469223427,
      "status": "SUCCEEDED",
      "context": {
        "clusters": [
          {
            "healthCheckType": "EC2",
            "placementConstraints": [],
            "stack": "t",
            "targetGroup": "",
            "ecsClusterName": "mccloman-3-test",
            "preferSourceCapacity": false,
            "securityGroupNames": [
              "no-ingress-sg"
            ],
            "availabilityZones": {
              "us-west-2": [
                "us-west-2a",
                "us-west-2b",
                "us-west-2c",
                "us-west-2d"
              ]
            },
            "capacity": {
              "min": 1,
              "desired": 1,
              "max": 1
            },
            "freeFormDetails": "e",
            "provider": "ecs",
            "serviceDiscoveryAssociations": [],
            "cloudProvider": "ecs",
            "imageDescription": {
              "registry": "index.docker.io",
              "imageId": "index.docker.io/nabuskey/public-test:echo",
              "fromTrigger": true,
              "tag": "echo",
              "repository": "nabuskey/public-test",
              "account": "my-ecr-registry"
            },
            "copySourceScalingPoliciesAndActions": false,
            "targetGroupMappings": [],
            "dockerLabels": {},
            "healthCheckGracePeriodSeconds": "",
            "launchType": "FARGATE",
            "networkMode": "awsvpc",
            "reservedMemory": 512,
            "taskDefinitionArtifact": {},
            "loadBalancers": [],
            "moniker": {
              "app": "test",
              "stack": "t",
              "detail": "e"
            },
            "useSourceCapacity": false,
            "placementStrategySequence": [],
            "tags": {},
            "iamRole": "None (No IAM role)",
            "computeUnits": 256,
            "placementStrategyName": "",
            "application": "test",
            "environmentVariables": {},
            "associatePublicIpAddress": false,
            "dockerImageCredentialsSecret": "None (No registry credentials)",
            "securityGroups": [],
            "strategy": "",
            "useTaskDefinitionArtifact": false,
            "account": "mccloman-3-ecs",
            "subnetType": "private-subnet1"
          }
        ]
      },
      "outputs": {},
      "tasks": [
        {
          "id": "1",
          "implementingClass": "com.netflix.spinnaker.orca.kato.pipeline.ParallelDeployStage.CompleteParallelDeployTask",
          "name": "completeParallelDeploy",
          "startTime": 1598469223318,
          "endTime": 1598469223374,
          "status": "SUCCEEDED",
          "stageStart": true,
          "stageEnd": true,
          "loopStart": false,
          "loopEnd": false
        }
      ],
      "requisiteStageRefIds": []
    }
  ],
  "startTime": 1598469152285,
  "endTime": 1598469223434,
  "status": "SUCCEEDED",
  "authentication": {
    "user": "anonymous",
    "allowedAccounts": [
      "mccloman-1-ecs",
      "mccloman-1",
      "my-ecr-registry"
    ]
  },
  "origin": "api",
  "trigger": {
    "type": "manual",
    "user": "[anonymous]",
    "parameters": {},
    "artifacts": [
      {
        "customKind": false,
        "reference": "index.docker.io/nabuskey/public-test:echo",
        "metadata": {},
        "name": "index.docker.io/nabuskey/public-test",
        "type": "docker/image",
        "version": "echo"
      }
    ],
    "notifications": [],
    "rebake": false,
    "dryRun": false,
    "strategy": false,
    "account": "my-ecr-registry",
    "repository": "nabuskey/public-test",
    "tag": "echo",
    "resolvedExpectedArtifacts": [],
    "expectedArtifacts": [],
    "registry": "index.docker.io",
    "eventId": "56855237-95b2-4a4f-ac4f-bf2232c792ed",
    "enabled": true,
    "executionId": "01EGP2Z7D8Z0BBYR39484SK2S0",
    "organization": "nabuskey",
    "preferred": false
  },
  "pipelineConfigId": "791ea0de-8c25-47b0-931a-7c7e8a9281d1",
  "notifications": [],
  "initialConfig": {},
  "systemNotifications": [],
  "spelEvaluator": "v4"
}

Test EC2 Application Deployment via Spinnaker Pipeline

Name of Tester: Manabu McCloskey
Date of Test: 08/26/2020
Title of Test: Test EC2 Application Deployment via Spinnaker Pipeline

Spinnaker Version: 1.21
Plugin Version: 0.0.1

Status: PASS

Step 1

In the provisioned account:
Create a EC2 server group
Create a load balancer
Create a security group.

Expected:

No errors returned.

Output:

No errors returned.

Test ECS Fargate Application Deployment via Spinnaker Pipeline

Name of Tester: Manabu McCloskey
Date of Test: 08/26/2020
Title of Test: Test ECS Fargate Application Deployment via Spinnaker Pipeline

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: PASS

Step 1

create a pipeline which creates a service in ECS Fargate that uses an account which have been provisioned through the plugin.

Expected:
{
  "clusters": [
    {
      "account": "test-3-ecs",
      "application": "test",
      "associatePublicIpAddress": false,
      "availabilityZones": {
        "us-west-2": [
          "us-west-2a",
          "us-west-2b",
          "us-west-2c",
          "us-west-2d"
        ]
      },
      "capacity": {
        "desired": 1,
        "max": 1,
        "min": 1
      },
      "cloudProvider": "ecs",
      "computeUnits": 256,
      "copySourceScalingPoliciesAndActions": false,
      "dockerImageCredentialsSecret": "None (No registry credentials)",
      "dockerLabels": {},
      "ecsClusterName": "test-3-test",
      "environmentVariables": {},
      "freeFormDetails": "e",
      "healthCheckGracePeriodSeconds": "",
      "healthCheckType": "EC2",
      "iamRole": "None (No IAM role)",
      "imageDescription": {
        "account": "my-ecr-registry",
        "fromTrigger": true,
        "imageId": "index.docker.io/nabuskey/public-test:echo",
        "registry": "index.docker.io",
        "repository": "nabuskey/public-test",
        "tag": "echo"
      },
      "launchType": "FARGATE",
      "loadBalancers": [],
      "moniker": {
        "app": "test",
        "detail": "e",
        "stack": "t"
      },
      "networkMode": "awsvpc",
      "placementConstraints": [],
      "placementStrategyName": "",
      "placementStrategySequence": [],
      "preferSourceCapacity": false,
      "provider": "ecs",
      "reservedMemory": 512,
      "securityGroupNames": [
        "no-ingress-sg"
      ],
      "securityGroups": [],
      "serviceDiscoveryAssociations": [],
      "stack": "t",
      "strategy": "",
      "subnetType": "private-subnet1",
      "tags": {},
      "targetGroup": "",
      "targetGroupMappings": [],
      "taskDefinitionArtifact": {},
      "useSourceCapacity": false,
      "useTaskDefinitionArtifact": false
    }
  ],
  "name": "Deploy",
  "type": "deploy"
}
Output:

Same as above.

Step 2

Execute the pipeline created above.

Expected:

Pipeline executes without any errors.

Output:
{
  "type": "PIPELINE",
  "id": "01EGNR1KV61FF25YQM64QDX69V",
  "application": "test",
  "name": "mccloman3",
  "buildTime": 1598457696350,
  "canceled": false,
  "limitConcurrent": true,
  "keepWaitingPipelines": false,
  "stages": [
    {
      "id": "01EGNR1M7476DTFHZ0FRSWE2DR",
      "refId": "1<1",
      "type": "createServerGroup",
      "name": "Deploy in us-west-2",
      "startTime": 1598457696557,
      "endTime": 1598457765359,
      "status": "SUCCEEDED",
      "context": {
        "healthCheckType": "EC2",
        "placementConstraints": [],
        "deploy.account.name": "test-3-ecs",
        "zeroDesiredCapacityCount": 0,
        "stack": "t",
        "targetGroup": "",
        "lastCapacityCheck": {
          "outOfService": 0,
          "up": 0,
          "failed": 0,
          "starting": 1,
          "down": 0,
          "succeeded": 0,
          "unknown": 0
        },
        "ecsClusterName": "test-3-test",
        "preferSourceCapacity": false,
        "availabilityZones": {
          "us-west-2": [
            "us-west-2a",
            "us-west-2b",
            "us-west-2c",
            "us-west-2d"
          ]
        },
        "source": {
          "serverGroupName": "test-t-e-v001",
          "asgName": "test-t-e-v001",
          "region": "us-west-2",
          "useSourceCapacity": false,
          "account": "test-3-ecs"
        },
        "type": "createServerGroup",
        "currentInstanceCount": 1,
        "freeFormDetails": "e",
        "serviceDiscoveryAssociations": [],
        "imageDescription": {
          "registry": "index.docker.io",
          "imageId": "index.docker.io/nabuskey/public-test:echo",
          "fromTrigger": true,
          "tag": "echo",
          "repository": "nabuskey/public-test",
          "account": "my-ecr-registry"
        },
        "kato.last.task.id": {
          "id": "80927326-97ab-4bcd-8d8b-bc32f51f78bc"
        },
        "targetGroupMappings": [],
        "dockerLabels": {},
        "healthCheckGracePeriodSeconds": "",
        "launchType": "FARGATE",
        "networkMode": "awsvpc",
        "interestingHealthProviderNames": [
          "ecs"
        ],
        "taskDefinitionArtifact": {},
        "kato.task.terminalRetryCount": 0,
        "loadBalancers": [],
        "zones": [],
        "placementStrategySequence": [],
        "tags": {},
        "kato.task.firstNotFoundRetry": -1,
        "capacitySnapshot": {
          "minSize": 1,
          "maxSize": 1,
          "desiredCapacity": 1
        },
        "name": "Deploy in us-west-2",
        "kato.tasks": [
          {
            "resultObjects": [
              {
                "ancestorServerGroupNameByRegion": {
                  "us-west-2": "test-t-e-v001"
                }
              },
              {
                "deployments": [],
                "serverGroupNames": [
                  "us-west-2:test-t-e-v002"
                ],
                "createdArtifacts": [],
                "deployedNamesByLocation": {},
                "deployedNames": [],
                "messages": [],
                "serverGroupNameByRegion": {
                  "us-west-2": "test-t-e-v002"
                }
              }
            ],
            "id": "80927326-97ab-4bcd-8d8b-bc32f51f78bc",
            "history": [
              {
                "phase": "ORCHESTRATION",
                "status": "Initializing Orchestration Task"
              },
              {
                "phase": "ORCHESTRATION",
                "status": "Processing op: CreateServerGroupAtomicOperation"
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Initializing Create Amazon ECS Server Group Operation..."
              },
              {
                "phase": "ECS_DEPLOY",
                "status": "Found ancestor server group, parsing details (name: test-t-e-v001)"
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Creating Amazon ECS Task Definition..."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Done creating Amazon ECS Task Definition..."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Creating 1 of test-t-e-v002 with arn:aws:ecs:us-west-2:123:task-definition/test-t-e:8 for test-3-ecs."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Done creating 1 of test-t-e-v002 with arn:aws:ecs:us-west-2:123:task-definition/test-t-e:8 for test-3-ecs."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Creating Amazon Application Auto Scaling Scalable Target Definition..."
              },
              {
                "phase": "CREATE_ECS_SERVER_GROUP",
                "status": "Done creating Amazon Application Auto Scaling Scalable Target Definition."
              },
              {
                "phase": "ORCHESTRATION",
                "status": "Orchestration completed."
              }
            ],
            "status": {
              "retryable": false,
              "completed": true,
              "failed": false
            }
          }
        ],
        "useTaskDefinitionArtifact": false,
        "notification.type": "createdeploy",
        "force.cache.refresh.errors": [],
        "securityGroupNames": [
          "no-ingress-sg"
        ],
        "capacity": {
          "min": 1,
          "desired": 1,
          "max": 1
        },
        "targetDesiredSize": 1,
        "provider": "ecs",
        "cloudProvider": "ecs",
        "kato.result.expected": false,
        "copySourceScalingPoliciesAndActions": false,
        "deploy.server.groups": {
          "us-west-2": [
            "test-t-e-v002"
          ]
        },
        "reservedMemory": 512,
        "processed.server.groups": [],
        "refreshed.server.groups": [],
        "moniker": {
          "app": "test",
          "stack": "t",
          "detail": "e"
        },
        "useSourceCapacity": false,
        "iamRole": "None (No IAM role)",
        "computeUnits": 256,
        "placementStrategyName": "",
        "application": "test",
        "environmentVariables": {},
        "associatePublicIpAddress": false,
        "dockerImageCredentialsSecret": "None (No registry credentials)",
        "securityGroups": [],
        "strategy": "",
        "kato.task.notFoundRetryCount": 0,
        "account": "test-3-ecs",
        "subnetType": "private-subnet1",
        "kato.task.lastStatus": "SUCCEEDED"
      },
      "outputs": {},
      "tasks": [
        {
          "id": "1",
          "implementingClass": "com.netflix.spinnaker.orca.kato.pipeline.strategy.DetermineSourceServerGroupTask",
          "name": "determineSourceServerGroup",
          "startTime": 1598457696633,
          "endTime": 1598457696989,
          "status": "SUCCEEDED",
          "stageStart": true,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "2",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.DetermineHealthProvidersTask",
          "name": "determineHealthProviders",
          "startTime": 1598457697052,
          "endTime": 1598457697134,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "3",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.CreateServerGroupTask",
          "name": "createServerGroup",
          "startTime": 1598457697176,
          "endTime": 1598457697655,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "4",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.MonitorKatoTask",
          "name": "monitorDeploy",
          "startTime": 1598457697707,
          "endTime": 1598457702870,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "5",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ServerGroupCacheForceRefreshTask",
          "name": "forceCacheRefresh",
          "startTime": 1598457702922,
          "endTime": 1598457713284,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "6",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.instance.WaitForUpInstancesTask",
          "name": "waitForUpInstances",
          "startTime": 1598457713297,
          "endTime": 1598457754890,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "7",
          "implementingClass": "com.netflix.spinnaker.orca.clouddriver.tasks.servergroup.ServerGroupCacheForceRefreshTask",
          "name": "forceCacheRefresh",
          "startTime": 1598457754897,
          "endTime": 1598457765220,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": false,
          "loopStart": false,
          "loopEnd": false
        },
        {
          "id": "8",
          "implementingClass": "com.netflix.spinnaker.orca.igor.tasks.GetCommitsTask",
          "name": "getCommits",
          "startTime": 1598457765228,
          "endTime": 1598457765349,
          "status": "SUCCEEDED",
          "stageStart": false,
          "stageEnd": true,
          "loopStart": false,
          "loopEnd": false
        }
      ],
      "syntheticStageOwner": "STAGE_BEFORE",
      "parentStageId": "01EGNR1M2Y0M1F26VXDP8WQB29",
      "requisiteStageRefIds": []
    },
    {
      "id": "01EGNR1M2Y0M1F26VXDP8WQB29",
      "refId": "1",
      "type": "deploy",
      "name": "Deploy",
      "startTime": 1598457696478,
      "endTime": 1598457765522,
      "status": "SUCCEEDED",
      "context": {
        "clusters": [
          {
            "healthCheckType": "EC2",
            "placementConstraints": [],
            "stack": "t",
            "targetGroup": "",
            "ecsClusterName": "test-3-test",
            "preferSourceCapacity": false,
            "securityGroupNames": [
              "no-ingress-sg"
            ],
            "availabilityZones": {
              "us-west-2": [
                "us-west-2a",
                "us-west-2b",
                "us-west-2c",
                "us-west-2d"
              ]
            },
            "capacity": {
              "min": 1,
              "desired": 1,
              "max": 1
            },
            "freeFormDetails": "e",
            "provider": "ecs",
            "serviceDiscoveryAssociations": [],
            "cloudProvider": "ecs",
            "imageDescription": {
              "registry": "index.docker.io",
              "imageId": "index.docker.io/nabuskey/public-test:echo",
              "fromTrigger": true,
              "tag": "echo",
              "repository": "nabuskey/public-test",
              "account": "my-ecr-registry"
            },
            "copySourceScalingPoliciesAndActions": false,
            "targetGroupMappings": [],
            "dockerLabels": {},
            "healthCheckGracePeriodSeconds": "",
            "launchType": "FARGATE",
            "networkMode": "awsvpc",
            "reservedMemory": 512,
            "taskDefinitionArtifact": {},
            "loadBalancers": [],
            "moniker": {
              "app": "test",
              "stack": "t",
              "detail": "e"
            },
            "useSourceCapacity": false,
            "placementStrategySequence": [],
            "tags": {},
            "iamRole": "None (No IAM role)",
            "computeUnits": 256,
            "placementStrategyName": "",
            "application": "test",
            "environmentVariables": {},
            "associatePublicIpAddress": false,
            "dockerImageCredentialsSecret": "None (No registry credentials)",
            "securityGroups": [],
            "strategy": "",
            "useTaskDefinitionArtifact": false,
            "account": "test-3-ecs",
            "subnetType": "private-subnet1"
          }
        ]
      },
      "outputs": {},
      "tasks": [
        {
          "id": "1",
          "implementingClass": "com.netflix.spinnaker.orca.kato.pipeline.ParallelDeployStage.CompleteParallelDeployTask",
          "name": "completeParallelDeploy",
          "startTime": 1598457765414,
          "endTime": 1598457765468,
          "status": "SUCCEEDED",
          "stageStart": true,
          "stageEnd": true,
          "loopStart": false,
          "loopEnd": false
        }
      ],
      "requisiteStageRefIds": []
    }
  ],
  "startTime": 1598457696422,
  "endTime": 1598457765574,
  "status": "SUCCEEDED",
  "authentication": {
    "user": "anonymous",
    "allowedAccounts": [
      "mccloman-1",
      "mccloman-1-ecs",
      "my-ecr-registry",
      "test-3",
      "test-3-ecs"
    ]
  },
  "origin": "api",
  "trigger": {
    "type": "manual",
    "user": "[anonymous]",
    "parameters": {},
    "artifacts": [
      {
        "customKind": false,
        "reference": "index.docker.io/nabuskey/public-test:echo",
        "metadata": {},
        "name": "index.docker.io/nabuskey/public-test",
        "type": "docker/image",
        "version": "echo"
      }
    ],
    "notifications": [],
    "rebake": false,
    "dryRun": false,
    "strategy": false,
    "account": "my-ecr-registry",
    "repository": "nabuskey/public-test",
    "tag": "echo",
    "resolvedExpectedArtifacts": [],
    "expectedArtifacts": [],
    "registry": "index.docker.io",
    "eventId": "11a1deeb-66d8-435e-a27a-2e91ad42a854",
    "enabled": true,
    "executionId": "01EGNR1KV61FF25YQM64QDX69V",
    "organization": "nabuskey",
    "preferred": false
  },
  "pipelineConfigId": "791ea0de-8c25-47b0-931a-7c7e8a9281d1",
  "notifications": [],
  "initialConfig": {},
  "systemNotifications": [],
  "spelEvaluator": "v4"
}

Test Sigv4 Signature on Requests Sent

Name of Tester: Manabu McCloskey
Date of Test: 08/26/20
Title of Test: Test Sigv4 Signature on Requests Sent

Spinnaker Version: 1.21.4
Plugin Version: 0.0.1

Status: Pass

Step 1

Create a API Gateway with IAM auth enabled on a GET method. Enable mock integration to return a valid payload.

{
    "httpMethod": "GET",
    "authorizationType": "AWS_IAM",
    "apiKeyRequired": false,
    "methodResponses": {
        "200": {
            "statusCode": "200",
            "responseModels": {
                "application/json": "Empty"
            }
        }
    },
    "methodIntegration": {
        "type": "AWS_PROXY",
        "httpMethod": "POST",
        "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123:function:spinMock/invocations",
        "passthroughBehavior": "WHEN_NO_MATCH",
        "contentHandling": "CONVERT_TO_TEXT",
        "timeoutInMillis": 29000,
        "cacheNamespace": "bgyoja",
        "cacheKeyParameters": [],
        "integrationResponses": {
            "200": {
                "statusCode": "200",
                "responseTemplates": {
                    "application/json": null
                }
            }
        }
    }
}
Expected:
{
  "SpinnakerAccounts": [
    {
      "AccountId": "123",
      "SpinnakerAccountName": "test-3",
      "Regions": [
        "us-west-2"
      ],
      "SpinnakerStatus": "ACTIVE",
      "SpinnakerAssumeRole": "role/spinnakerManaged",
      "SpinnakerProviders": [
        "ecs",
        "lambda",
        "ec2"
      ],
      "CreatedAt": "1598027546352337694",
      "UpdatedAt": "2020-08-21T16:32:26.352337694Z"
    }
  ],
  "Pagination": {
    "NextUrl": ""
  }
}

Step 2

Run clouddriver with plugin as described in the README file with the url configuration pointing to the mock integration end point.

Expected:

No error in logs. Correct accounts are show in the /credentials endpoint.

Output:

No error in logs. Accounts show up correctly.

[
  {
    "accountId": "123",
    "accountType": "test-3",
    "challengeDestructiveActions": false,
    "cloudProvider": "aws",
    "environment": "test-3",
    "name": "test-3",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "aws"
  },
  {
    "accountId": "123",
    "accountType": "ecs",
    "challengeDestructiveActions": false,
    "cloudProvider": "ecs",
    "environment": "test-3",
    "name": "test-3-ecs",
    "permissions": {},
    "primaryAccount": false,
    "providerVersion": "v1",
    "requiredGroupMembership": [],
    "type": "ecs"
  }
]

clouddriver issue after removing aws accounts

after commenting out all aws accounts clouddriver didn't start properly:

Plugin Version: 1.1.0
Armory Spinnaker Version: 2.24.0

Clouddriver Logs:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-04-15 18:40:14.657 ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'configurationRefreshListener' 
defined in URL [jar:file:/opt/clouddriver/lib/clouddriver-web-7.2.1-20210105155350.jar!/com/netflix/spinnaker/clouddriver/listeners/ConfigurationRefreshListener.class]: 
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'ecsCredentialsInializerSynchronizable' defined in class path resource [com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.class]: 
Unsatisfied dependency expressed through method 'ecsCredentialsInializerSynchronizable' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ecsCredentialsLoader': Invocation of init method failed; 
nested exception is java.lang.ClassCastException: class com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials cannot be cast to class com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials (com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials 
and com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials are in unnamed module of loader 'app')
main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyEx
ception: Error creating bean with name 'configurationRefreshListener' defined in URL [jar:file:/opt/clouddriver/lib/clouddriver-web-7.2.1-20210105155350.jar!/com/netflix/spinnaker/clouddriver/listeners/ConfigurationRefreshListener.class
]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ecsCredentialsInializerSynchronizable' defined in
class path resource [com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.class]: Unsatisfied dependency expressed through method 'ecsCredentialsInializerSynchronizable' parameter 0; nested exception is org.springfra
mework.beans.factory.BeanCreationException: Error creating bean with name 'ecsCredentialsLoader': Invocation of init method failed; nested exception is java.lang.ClassCastException: class com.netflix.spinnaker.clouddriver.aws.security.N
etflixAmazonCredentials cannot be cast to class com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials (com.netflix.spinnaker.clouddriver.aws.security.NetflixAmazonCredentials and com.netflix.spinnaker.clouddr
iver.aws.security.NetflixAssumeRoleAmazonCredentials are in unnamed module of loader 'app')
2021-04-15 18:40:25.444  WARN 1 --- [           main] .s.c.a.CommonAnnotationBeanPostProcessor : Destroy method on bean with name 'operationsController' threw an exception: java.lang.IllegalArgumentException: Field (null) is not contain
ed in Row ("task_states"."id", "task_states"."task_id", "task_states"."created_at", "task_states"."state", "task_states"."phase", "task_states"."status", "task_states"."task_id", "task_states"."created", "tasks"."id", "tasks"."request_i
d", "tasks"."owner_id", "tasks"."created_at", "tasks"."saga_ids")
2021-04-15 18:40:25.469  INFO 1 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Shutting down ExecutorService 'vaultThreadPoolTaskScheduler'
2021-04-15 18:40:25.472  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2021-04-15 18:39:58.683  INFO 1 --- [           main] c.a.a.s.p.registration.AccountsStatus    : Attempting to obtain AWS credentials from default chain.
2021-04-15 18:40:01.470  INFO 1 --- [           main] c.a.a.s.p.registration.AccountsStatus    : Received a valid response from remote host.
2021-04-15 18:40:01.470  INFO 1 --- [           main] c.a.a.s.p.registration.AccountsStatus    : Finished gathering accounts from remote host. Processing 32 accounts.
2021-04-15 18:40:01.539  INFO 1 --- [           main] c.a.a.s.p.registration.AccountsStatus    : Setting last sync attempt time to 2021-04-07T23:55:38.760363+00:00
2021-04-15 18:40:01.540  INFO 1 --- [           main] c.a.a.s.p.registration.AccountsStatus    : Converting 32 accounts to Spinnaker account types.
2021-04-15 18:40:01.540  INFO 1 --- [           main] c.a.a.s.plugin.registration.Response     : Converting to Spinnaker account type.
2021-04-15 19:00:55.051  WARN 1 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refres
h attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'configurationRefreshListener' defined in URL [jar:file:/opt/
clouddriver/lib/clouddriver-web-7.2.1-20210105155350.jar!/com/netflix/spinnaker/clouddriver/listeners/ConfigurationRefreshListener.class]: Unsatisfied dependency expres
sed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ecsCredentials
InializerSynchronizable' defined in class path resource [com/netflix/spinnaker/clouddriver/ecs/security/EcsCredentialsInitializer.class]: Unsatisfied dependency express
ed through method 'ecsCredentialsInializerSynchronizable' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean 
with name 'ecsCredentialsLoader': Invocation of init method failed; nested exception is java.lang.ClassCastException: class com.netflix.spinnaker.clouddriver.aws.securi
ty.NetflixAmazonCredentials cannot be cast to class com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials (com.netflix.spinnaker.clouddriver
.aws.security.NetflixAmazonCredentials and com.netflix.spinnaker.clouddriver.aws.security.NetflixAssumeRoleAmazonCredentials are in unnamed module of loader 'app')

More logs and potential issue with UpdatedAt.gt/lastSyncTime or initial load

One of our accounts went through the following chain of log/output:

Could not find account, Account-A. Checking remote repository.
->
Getting account information from <repo_url>.
->
????
->
Could not find account, Account-A, in remote repository.

Specifically it seems to have gone through these lines:
https://github.com/awslabs/aws-account-registration-plugin-spinnaker/blob/master/account-registration/src/main/java/com/amazon/aws/spinnaker/plugin/registration/LazyLoadCredentialsRepository.java#L42-L49
->
https://github.com/awslabs/aws-account-registration-plugin-spinnaker/blob/master/account-registration/src/main/java/com/amazon/aws/spinnaker/plugin/registration/AmazonPollingSynchronizer.java#L88-L91
->
https://github.com/awslabs/aws-account-registration-plugin-spinnaker/blob/master/account-registration/src/main/java/com/amazon/aws/spinnaker/plugin/registration/AccountsStatus.java#L88-L91
->
https://github.com/awslabs/aws-account-registration-plugin-spinnaker/blob/master/account-registration/src/main/java/com/amazon/aws/spinnaker/plugin/registration/AccountsStatus.java#L184-L186
->
https://github.com/awslabs/aws-account-registration-plugin-spinnaker/blob/master/account-registration/src/main/java/com/amazon/aws/spinnaker/plugin/registration/AccountsStatus.java#L195
-> maybe
https://github.com/awslabs/aws-account-registration-plugin-spinnaker/blob/master/account-registration/src/main/java/com/amazon/aws/spinnaker/plugin/registration/AccountsStatus.java#L242

It seems this way based on what I'm not seeing in the ???? (following 2nd link and onwards) and what the end-state/last-line is of the log output I've posted.

While there is 2 log.debug outputs in the trail of lines that I've posted, we don't have debugging enabled - since that would be a bit too verbose (all other micro-services would output as well).

(Ask/Issue 1)
It would be nice to have more log.info outputs in more critical places - to indicate what happened/how it exited/returned something. For instance, what happens in the getResourceFromRemoteHost, was it actually because the accounts list was null or empty. Or, what was the last sync up time used in callApiGateway. Basically, that trail I was able to deduce (though, lacking confidence) based on what I'm not seeing rather than seeing in the logs.

(Ask/Issue 2)
Following that trail, leads me to believe there's something fishy/weird happening around UpdatedAt.gt/lastSyncTime or the initial account loading.
Account-A has been tagged as both an AWS(EC2) and ECS account. It does appear to be configured as an AWS(EC2) account, but not as an ECS account. It either failed to load initially - but I can't find the evidence - or it failed to update/re-register because (possibly) lastSyncTime was already ahead of UpdatedAt.gt that the account returns when it would have had the chance to re-register. Though, lacking enough information to pin down exactly where the problem is.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.