Skip to content

Commit

Permalink
feat: Get tags from services and set ad-hoc run-task
Browse files Browse the repository at this point in the history
  • Loading branch information
guikcd committed Aug 30, 2024
1 parent 5ae7be6 commit ee0f18e
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 42 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@ To turn on [Amazon ECS-managed tags](https://docs.aws.amazon.com/AmazonECS/lates
enable-ecs-managed-tags: true
```

You can propagate your custom tags from your existing service using `propagate-tags`:

```yaml
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: task-definition.json
service: my-service
cluster: my-cluster
wait-for-service-stability: true
propagate-tags: SERVICE
```

## Credentials and Region

This action relies on the [default behavior of the AWS SDK for Javascript](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html) to determine AWS credentials and region.
Expand Down Expand Up @@ -288,6 +301,27 @@ In the following example, the service would not be updated until the ad-hoc task
Overrides and VPC networking options are available as well. See [action.yml](action.yml) for more details. The `FARGATE`
launch type requires `awsvpc` network mode in your task definition and you must specify a network configuration.

### Tags

To tag your tasks:

* to turn on Amazon ECS-managed tags (`aws:ecs:clusterName`), use `enable-ecs-managed-tags`
* for custom tags, use `run-task-tags`

```yaml
- name: Deploy to Amazon ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: task-definition.json
service: my-service
cluster: my-cluster
wait-for-service-stability: true
run-task: true
enable-ecs-managed-tags: true
run-task-tags: '[{"key": "project", "value": "myproject"}]'
wait-for-task-stopped: true
```

## Troubleshooting

This action emits debug logs to help troubleshoot deployment failures. To see the debug logs, create a secret named `ACTIONS_STEP_DEBUG` with value `true` in your repository.
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,18 @@ inputs:
run-task-started-by:
description: "A name to use for the startedBy tag when running a task outside of a service. Will default to 'GitHub-Actions'."
required: false
run-task-tags:
description: 'A JSON array of tags'
required: false
wait-for-task-stopped:
description: 'Whether to wait for the task to stop when running it outside of a service. Will default to not wait.'
required: false
enable-ecs-managed-tags:
description: "Determines whether to turn on Amazon ECS managed tags 'aws:ecs:serviceName' and 'aws:ecs:clusterName' for the tasks in the service."
required: false
propagate-tags:
description: "Determines whether to propagate the tags from the 'TASK_DEFINITION' or the 'SERVICE' to the task. Will default to 'NONE'"
required: false
outputs:
task-definition-arn:
description: 'The ARN of the registered ECS task definition'
Expand Down
18 changes: 11 additions & 7 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [
];

// Method to run a stand-alone task with desired inputs
async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags) {
async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, runTaskTags) {
core.info('Running task')

const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false';
Expand Down Expand Up @@ -61,7 +61,8 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa
},
launchType: launchType,
networkConfiguration: Object.keys(awsvpcConfiguration).length === 0 ? null : { awsvpcConfiguration: awsvpcConfiguration },
enableECSManagedTags: enableECSManagedTags
enableECSManagedTags: enableECSManagedTags,
tags: runTaskTags
});

core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`)
Expand Down Expand Up @@ -135,15 +136,16 @@ async function tasksExitCode(ecs, clusterName, taskArns) {
}

// Deploy to a service that uses the 'ECS' deployment controller
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags) {
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags) {
core.debug('Updating the service');

let params = {
cluster: clusterName,
service: service,
taskDefinition: taskDefArn,
forceNewDeployment: forceNewDeployment,
enableECSManagedTags: enableECSManagedTags
enableECSManagedTags: enableECSManagedTags,
propagateTags: propagateTags
};

// Add the desiredCount property only if it is defined and a number.
Expand Down Expand Up @@ -401,7 +403,9 @@ async function run() {
const desiredCount = parseInt((core.getInput('desired-count', {required: false})));
const enableECSManagedTagsInput = core.getInput('enable-ecs-managed-tags', { required: false }) || 'false';
const enableECSManagedTags = enableECSManagedTagsInput.toLowerCase() === 'true';

const propagateTags = core.getInput('propagate-tags', { required: false }) || 'NONE';
const runTaskTags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]');

// Register the task definition
core.debug('Registering the task definition');
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
Expand All @@ -428,7 +432,7 @@ async function run() {
core.debug(`shouldRunTask: ${shouldRunTask}`);
if (shouldRunTask) {
core.debug("Running ad-hoc task...");
await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags);
await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, runTaskTags);
}

// Update the service with the new task definition
Expand All @@ -452,7 +456,7 @@ async function run() {
if (!serviceResponse.deploymentController || !serviceResponse.deploymentController.type || serviceResponse.deploymentController.type === 'ECS') {
// Service uses the 'ECS' deployment controller, so we can call UpdateService
core.debug('Updating service...');
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags);
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags);

} else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') {
// Service uses CodeDeploy, so we should start a CodeDeploy deployment
Expand Down
18 changes: 11 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const IGNORED_TASK_DEFINITION_ATTRIBUTES = [
];

// Method to run a stand-alone task with desired inputs
async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags) {
async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, runTaskTags) {
core.info('Running task')

const waitForTask = core.getInput('wait-for-task-stopped', { required: false }) || 'false';
Expand Down Expand Up @@ -55,7 +55,8 @@ async function runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSMa
},
launchType: launchType,
networkConfiguration: Object.keys(awsvpcConfiguration).length === 0 ? null : { awsvpcConfiguration: awsvpcConfiguration },
enableECSManagedTags: enableECSManagedTags
enableECSManagedTags: enableECSManagedTags,
tags: runTaskTags
});

core.debug(`Run task response ${JSON.stringify(runTaskResponse)}`)
Expand Down Expand Up @@ -129,15 +130,16 @@ async function tasksExitCode(ecs, clusterName, taskArns) {
}

// Deploy to a service that uses the 'ECS' deployment controller
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags) {
async function updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags) {
core.debug('Updating the service');

let params = {
cluster: clusterName,
service: service,
taskDefinition: taskDefArn,
forceNewDeployment: forceNewDeployment,
enableECSManagedTags: enableECSManagedTags
enableECSManagedTags: enableECSManagedTags,
propagateTags: propagateTags
};

// Add the desiredCount property only if it is defined and a number.
Expand Down Expand Up @@ -395,7 +397,9 @@ async function run() {
const desiredCount = parseInt((core.getInput('desired-count', {required: false})));
const enableECSManagedTagsInput = core.getInput('enable-ecs-managed-tags', { required: false }) || 'false';
const enableECSManagedTags = enableECSManagedTagsInput.toLowerCase() === 'true';

const propagateTags = core.getInput('propagate-tags', { required: false }) || 'NONE';
const runTaskTags = JSON.parse(core.getInput('run-task-tags', { required: false }) || '[]');

// Register the task definition
core.debug('Registering the task definition');
const taskDefPath = path.isAbsolute(taskDefinitionFile) ?
Expand All @@ -422,7 +426,7 @@ async function run() {
core.debug(`shouldRunTask: ${shouldRunTask}`);
if (shouldRunTask) {
core.debug("Running ad-hoc task...");
await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags);
await runTask(ecs, clusterName, taskDefArn, waitForMinutes, enableECSManagedTags, runTaskTags);
}

// Update the service with the new task definition
Expand All @@ -446,7 +450,7 @@ async function run() {
if (!serviceResponse.deploymentController || !serviceResponse.deploymentController.type || serviceResponse.deploymentController.type === 'ECS') {
// Service uses the 'ECS' deployment controller, so we can call UpdateService
core.debug('Updating service...');
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags);
await updateEcsService(ecs, clusterName, service, taskDefArn, waitForService, waitForMinutes, forceNewDeployment, desiredCount, enableECSManagedTags, propagateTags);

} else if (serviceResponse.deploymentController.type === 'CODE_DEPLOY') {
// Service uses CodeDeploy, so we should start a CodeDeploy deployment
Expand Down
Loading

0 comments on commit ee0f18e

Please sign in to comment.