Skip to main content

Manage An AWS EC2 Instance

In the following guide, you are going to create self-service actions in Port that execute a GitHub workflow to manage an EC2 instance in the following ways:

  1. Terminate an Instance
  2. Reboot an instance
  3. Resize an Autoscaling Group

Prerequisites​

  1. Install Port's GitHub app by clicking here.
  2. Use the Port AWS exporter to ingest AWS EC2 instances and autoscaling groups into Port to create the blueprints and entities.
Using the Port AWS exporter

The Port AWS exporter supports ingesting different AWS resource types. For the sake of this guide, you may run the following command in the installation step to only ingest relevant resources:

terraform apply -var 'resources=["ec2_instance", "autoscaling_group"]'
  1. Create the following GitHub Action secrets:
    • Port credentials:

    • AWS Cloud credentials:

      • AWS_ACCESS_KEY_ID: Your AWS access key.
      • AWS_SECRET_ACCESS_KEY: Your AWS secret access key.
      • AWS_REGION - the aws region which constains your ec2 instances.

Terminating an Instance​

  1. Create the Port action on the ec2Instance blueprint:
    • Head to the self-service page.
    • Click on the + New Action button.
    • Click on the {...} Edit JSON button.
    • Copy and paste the following JSON configuration into the editor:
Port Action: Terminate EC2 Instance
tip
  • <GITHUB-ORG> - your GitHub organization or user name.
  • <GITHUB-REPO-NAME> - your GitHub repository name.
{
"identifier": "ec2Instance_terminate_instance",
"title": "Terminate Instance",
"description": "Terminate an EC2 Instance",
"trigger": {
"type": "self-service",
"operation": "DELETE",
"userInputs": {
"properties": {},
"required": []
},
"blueprintIdentifier": "ec2Instance"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB-ORG>",
"repo": "<GITHUB-REPO-NAME>",
"workflow": "terminate-instance.yml",
"workflowInputs": {
"{{if (.inputs | has(\"ref\")) then \"ref\" else null end}}": "{{.inputs.\"ref\"}}",
"port_payload": {
"action": "{{ .action.identifier[(\"ec2Instance_\" | length):] }}",
"resourceType": "run",
"status": "TRIGGERED",
"trigger": "{{ .trigger | {by, origin, at} }}",
"context": {
"entity": "{{.entity.identifier}}",
"blueprint": "{{.action.blueprint}}",
"runId": "{{.run.id}}"
},
"payload": {
"entity": "{{ (if .entity == {} then null else .entity end) }}",
"action": {
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB-ORG>",
"repo": "<GITHUB-REPO-NAME>",
"workflow": "terminate-instance.yml",
"omitUserInputs": true,
"omitPayload": false,
"reportWorkflowStatus": true
},
"trigger": "{{.trigger.operation}}"
},
"properties": {},
"censoredProperties": "{{.action.encryptedProperties}}"
}
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false,
"publish": true
}
  1. Create a workflow file under .github/workflows/terminate-instance.yaml with the following content:
GitHub workflow script
terminate-instance.yaml
name: Terminate EC2 Instance

on:
workflow_dispatch: # Trigger this workflow manually
inputs:
port_payload:
required: true
description: "Port's payload, including details for who triggered the action and general context (blueprint, run id, etc...)"
type: string

jobs:
terminate-instance:
runs-on: ubuntu-latest
steps:
- name: Inform Port about terminating EC2 instance
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.getport.io
operation: PATCH_RUN
runId: ${{fromJson(inputs.port_payload).context.runId}}
logMessage: Configuring AWS credentials and terminating EC2 instance with ID ${{ github.event.inputs.instance_id }}

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

- name: Terminate EC2 instance
run: aws ec2 terminate-instances --instance-ids ${{ github.event.inputs.instance_id }}

- name: Inform Port about status of terminating EC2 instance
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.getport.io
operation: PATCH_RUN
runId: ${{fromJson(inputs.port_payload).context.runId}}
logMessage: EC2 instance with ID ${{ github.event.inputs.instance_id }} terminated successfully
  1. Trigger the action from Port's self-service page or from the context menu of an EC2 entity.

Rebooting an Instance​

  1. Create the Port action on the ec2Instance blueprint:
    • Head to the self-service page.
    • Click on the + New Action button.
    • Click on the {...} Edit JSON button.
    • Copy and paste the following JSON configuration into the editor:
Port Action: Reboot EC2 Instance
tip
  • <GITHUB-ORG> - your GitHub organization or user name.
  • <GITHUB-REPO-NAME> - your GitHub repository name.
{
"identifier": "ec2Instance_reboot_instance",
"title": "Reboot Instance",
"description": "Reboot an EC2 Instance",
"trigger": {
"type": "self-service",
"operation": "DAY-2",
"userInputs": {
"properties": {},
"required": []
},
"blueprintIdentifier": "ec2Instance"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB-ORG>",
"repo": "<GITHUB-REPO-NAME>",
"workflow": "reboot-instance.yml",
"workflowInputs": {
"{{if (.inputs | has(\"ref\")) then \"ref\" else null end}}": "{{.inputs.\"ref\"}}",
"port_payload": {
"action": "{{ .action.identifier[(\"ec2Instance_\" | length):] }}",
"resourceType": "run",
"status": "TRIGGERED",
"trigger": "{{ .trigger | {by, origin, at} }}",
"context": {
"entity": "{{.entity.identifier}}",
"blueprint": "{{.action.blueprint}}",
"runId": "{{.run.id}}"
},
"payload": {
"entity": "{{ (if .entity == {} then null else .entity end) }}",
"action": {
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB-ORG>",
"repo": "<GITHUB-REPO-NAME>",
"workflow": "reboot-instance.yml",
"omitUserInputs": true,
"omitPayload": false,
"reportWorkflowStatus": true
},
"trigger": "{{.trigger.operation}}"
},
"properties": {},
"censoredProperties": "{{.action.encryptedProperties}}"
}
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false,
"publish": true
}
  1. Create a workflow file under .github/workflows/reboot-instance.yaml with the following content:
GitHub workflow script
reboot-instance.yaml
name: Reboot EC2 Instance

on:
workflow_dispatch: # Trigger this workflow manually
inputs:
port_payload:
required: true
description: "Port's payload, including details for who triggered the action and general context (blueprint, run id, etc...)"
type: string

jobs:
reboot-instance:
runs-on: ubuntu-latest
steps:
- name: Inform Port of workflow start
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.getport.io
operation: PATCH_RUN
runId: ${{fromJson(inputs.port_payload).context.runId}}
logMessage: Configuring AWS credentials and reboot EC2 instance with ID ${{ fromJson(inputs.port_payload).payload.entity.identifier }}

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

- name: Reboot EC2 instance
run: aws ec2 reboot-instances --instance-ids ${{ fromJson(inputs.port_payload).payload.entity.identifier }}

- name: Inform Port about status of rebooting EC2 instance
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.getport.io
operation: PATCH_RUN
runId: ${{fromJson(inputs.port_payload).context.runId}}
logMessage: EC2 instance with ID ${{ fromJson(inputs.port_payload).payload.entity.identifier }} rebooted successfully
  1. Trigger the action from Port's self-service page or from the context menu of an EC2 entity.

Resize Autoscaling Group​

  1. Create the Port action on the Autoscaling Group blueprint:
    • Head to the self-service page.
    • Click on the + New Action button.
    • Click on the {...} Edit JSON button.
    • Copy and paste the following JSON configuration into the editor:
Port Action: Resize Autoscaling Group
tip
  • <GITHUB-ORG> - your GitHub organization or user name.
  • <GITHUB-REPO-NAME> - your GitHub repository name.
{
"identifier": "awsAutoScalingGroup_resize_autoscaling_group",
"title": "Resize Autoscaling Group",
"trigger": {
"type": "self-service",
"operation": "DAY-2",
"userInputs": {
"properties": {
"minimum_capacity": {
"icon": "DefaultProperty",
"title": "Minimum Capacity",
"description": "Minimum number of instances",
"type": "number",
"default": 1,
"minimum": 0
},
"maximum_capacity": {
"icon": "DefaultProperty",
"title": "Maximum Capacity",
"type": "number",
"default": 1,
"minimum": 1
},
"desired_capacity": {
"title": "Desired Capacity",
"type": "number",
"default": 1
}
},
"required": [
"desired_capacity",
"maximum_capacity",
"minimum_capacity"
],
"order": [
"minimum_capacity",
"maximum_capacity",
"desired_capacity"
]
},
"blueprintIdentifier": "awsAutoScalingGroup"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB-ORG>",
"repo": "<GITHUB-REPO-NAME>",
"workflow": "resize-asg.yml",
"workflowInputs": {
"{{if (.inputs | has(\"ref\")) then \"ref\" else null end}}": "{{.inputs.\"ref\"}}",
"{{if (.inputs | has(\"minimum_capacity\")) then \"minimum_capacity\" else null end}}": "{{.inputs.\"minimum_capacity\"}}",
"{{if (.inputs | has(\"maximum_capacity\")) then \"maximum_capacity\" else null end}}": "{{.inputs.\"maximum_capacity\"}}",
"{{if (.inputs | has(\"desired_capacity\")) then \"desired_capacity\" else null end}}": "{{.inputs.\"desired_capacity\"}}",
"port_payload": {
"action": "{{ .action.identifier[(\"awsAutoScalingGroup_\" | length):] }}",
"resourceType": "run",
"status": "TRIGGERED",
"trigger": "{{ .trigger | {by, origin, at} }}",
"context": {
"entity": "{{.entity.identifier}}",
"blueprint": "{{.action.blueprint}}",
"runId": "{{.run.id}}"
},
"payload": {
"entity": "{{ (if .entity == {} then null else .entity end) }}",
"action": {
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB-ORG>",
"repo": "<GITHUB-REPO-NAME>",
"workflow": "resize-asg.yml",
"omitUserInputs": false,
"omitPayload": false,
"reportWorkflowStatus": true
},
"trigger": "{{.trigger.operation}}"
},
"properties": {
"{{if (.inputs | has(\"minimum_capacity\")) then \"minimum_capacity\" else null end}}": "{{.inputs.\"minimum_capacity\"}}",
"{{if (.inputs | has(\"maximum_capacity\")) then \"maximum_capacity\" else null end}}": "{{.inputs.\"maximum_capacity\"}}",
"{{if (.inputs | has(\"desired_capacity\")) then \"desired_capacity\" else null end}}": "{{.inputs.\"desired_capacity\"}}"
},
"censoredProperties": "{{.action.encryptedProperties}}"
}
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false,
"publish": true
}


  1. Create a workflow file under .github/workflows/resize-asg.yaml with the following content:
GitHub workflow script
resize-asg.yaml
name: Resize Autoscaling Group

on:
workflow_dispatch:
inputs:
desired_capacity:
description: 'New desired capacity'
required: true
minimum_capacity:
description: 'Minimum size of the Auto Scaling Group'
required: true
maximum_capacity:
description: 'Maximum size of the Auto Scaling Group'
required: true
port_payload:
required: true
description: "Port's payload, including details for who triggered the action and general context (blueprint, run id, etc...)"
type: string

jobs:
resize-asg:
runs-on: ubuntu-latest
steps:
- name: Inform Port about workflow start
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.getport.io
operation: PATCH_RUN
runId: ${{fromJson(inputs.port_payload).context.runId}}
logMessage: Configuring AWS credentials


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

- name: Resize Auto Scaling Group
run: |
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name ${{ fromJson(inputs.port_payload).payload.entity.title }} \
--desired-capacity ${{ github.event.inputs.desired_capacity }} \
--min-size ${{ github.event.inputs.minimum_capacity }} \
--max-size ${{ github.event.inputs.maximum_capacity }}

- name: Inform Port about status of autoscaling group
uses: port-labs/port-github-action@v1
with:
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.getport.io
operation: PATCH_RUN
runId: ${{fromJson(inputs.port_payload).context.runId}}
logMessage: Resized EC2 Auto Scaling Group ${{ fromJson(inputs.port_payload).payload.entity.title }} to ${{ github.event.inputs.desired_capacity }} instances
  1. Trigger the action from Port's self-service page or from the context menu of an Auto Scaling Group entity.