Deploy AWS resources using AWS CloudFormation
This example demonstrates how to deploy an AWS resource using an AWS CloudFormation template, via Port Actions.
We will use an AWS managed GitHub Action called aws-actions/aws-cloudformation-github-deploy.
This guide includes one or more steps that require integration with GitHub.
Port supports two GitHub integrations:
- GitHub (Legacy) - uses a GitHub app, which is soon to be deprecated.
- GitHub (Ocean) - uses the Ocean framework, recommended for new integrations.
Both integration options are present in this guide via tabs, choose the one that fits your needs.
Steps
-
Create the following GitHub action secrets:
PORT_CLIENT_ID- Port Client ID learn more.PORT_CLIENT_SECRET- Port Client Secret learn more.AWS_ACCESS_KEY_ID- AWS credentials.AWS_SECRET_ACCESS_KEY- AWS credentials.AWS_REGION- AWS region name to deploy your resources to.
-
Install the relevant GitHub integration:
- GitHub (Legacy)
- GitHub (Ocean)
Install Port's GitHub app by clicking here.
Install GitHub ocean.
-
Create a Port blueprint with the following JSON definition (choose your desired resource):
- EC2 Instance
- S3 Bucket
- RDS Instance
Port EC2 Instance Blueprint
{
"identifier": "ec2Instance",
"description": "AWS EC2 Instance",
"title": "EC2 Instance",
"icon": "EC2",
"schema": {
"properties": {
"instance_name": {
"title": "Instance Name",
"type": "string"
},
"instance_type": {
"title": "Instance Type",
"type": "string"
},
"image_id": {
"title": "Image ID",
"type": "string"
},
"key_pair_name": {
"title": "Key Pair Name",
"type": "string"
},
"security_group_ids": {
"title": "Security Group IDs",
"type": "string"
}
},
"required": [
"instance_name",
"instance_type",
"image_id",
"key_pair_name",
"security_group_ids"
]
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Port S3 Bucket Blueprint
{
"identifier": "s3_bucket",
"title": "S3 Bucket",
"icon": "S3",
"schema": {
"properties": {
"bucket_name": {
"title": "Bucket Name",
"type": "string",
"minLength": 3,
"maxLength": 63,
"icon": "DefaultProperty"
},
"bucket_acl": {
"icon": "DefaultProperty",
"title": "Bucket ACL",
"type": "string",
"default": "Private"
}
},
"required": ["bucket_name", "bucket_acl"]
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
Port RDS Instance Blueprint
{
"identifier": "rds_instance",
"title": "RDS Instance",
"icon": "AmazonRDS",
"schema": {
"properties": {
"db_instance_identifier": {
"title": "DB Instance Identifier",
"type": "string",
"minLength": 1,
"maxLength": 63,
"icon": "DefaultProperty"
},
"db_master_password": {
"icon": "DefaultProperty",
"title": "DB Master Password",
"type": "string"
},
"db_master_username": {
"title": "DB Master Username",
"type": "string",
"minLength": 1,
"maxLength": 63,
"icon": "DefaultProperty"
},
"db_engine": {
"title": "DB Engine",
"type": "string",
"icon": "DefaultProperty"
},
"allocated_storage": {
"title": "Allocated Storage",
"type": "number",
"default": 20,
"minimum": 5,
"maximum": 1000,
"icon": "DefaultProperty"
},
"db_instance_class": {
"title": "DB Instance Class",
"type": "string",
"icon": "DefaultProperty"
}
},
"required": [
"db_instance_identifier",
"db_master_password",
"db_master_username",
"db_engine",
"allocated_storage",
"db_instance_class"
]
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
- Create Port Action using the following JSON definition:
Please make sure to modify GITHUB_ORG, GITHUB_REPO and GITHUB_WORKFLOW_FILE placeholders to match your environment.
- EC2 Instance
- S3 Bucket
- RDS Instance
Deploy EC2 self-service action
- GitHub (Legacy)
- GitHub (Ocean)
{
"identifier": "deploy_ec2_instance",
"title": "Deploy EC2 Instance",
"icon": "EC2",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"instance_name": {
"title": "Instance Name",
"type": "string"
},
"instance_type": {
"title": "Instance Type",
"type": "string",
"default": "t2.micro",
"enum": ["t2.micro", "t2.small"],
"enumColors": {
"t2.micro": "lightGray",
"t2.small": "lightGray"
}
},
"image_id": {
"title": "Image ID",
"type": "string"
},
"key_pair_name": {
"title": "Key Pair Name",
"type": "string"
},
"security_group_ids": {
"title": "Security Group IDs",
"icon": "DefaultProperty",
"type": "string",
"description": "Use comma delimited values for multiple SGs"
}
},
"required": [
"instance_name",
"instance_type",
"image_id",
"key_pair_name",
"security_group_ids"
],
"order": [
"instance_name",
"instance_type",
"image_id",
"key_pair_name",
"security_group_ids"
]
},
"blueprintIdentifier": "ec2Instance"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "<GITHUB_WORKFLOW_FILE>",
"workflowInputs": {
"instance_name": "{{ .inputs.\"instance_name\" }}",
"instance_type": "{{ .inputs.\"instance_type\" }}",
"image_id": "{{ .inputs.\"image_id\" }}",
"key_pair_name": "{{ .inputs.\"key_pair_name\" }}",
"security_group_ids": "{{ .inputs.\"security_group_ids\" }}",
"port_context": {
"entity": "{{ .entity }}",
"blueprint": "{{ .action.blueprint }}",
"runId": "{{ .run.id }}",
"trigger": "{{ .trigger }}"
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false
}
{
"identifier": "deploy_ec2_instance",
"title": "Deploy EC2 Instance",
"icon": "EC2",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"instance_name": {
"title": "Instance Name",
"type": "string"
},
"instance_type": {
"title": "Instance Type",
"type": "string",
"default": "t2.micro",
"enum": ["t2.micro", "t2.small"],
"enumColors": {
"t2.micro": "lightGray",
"t2.small": "lightGray"
}
},
"image_id": {
"title": "Image ID",
"type": "string"
},
"key_pair_name": {
"title": "Key Pair Name",
"type": "string"
},
"security_group_ids": {
"title": "Security Group IDs",
"icon": "DefaultProperty",
"type": "string",
"description": "Use comma delimited values for multiple SGs"
}
},
"required": [
"instance_name",
"instance_type",
"image_id",
"key_pair_name",
"security_group_ids"
],
"order": [
"instance_name",
"instance_type",
"image_id",
"key_pair_name",
"security_group_ids"
]
},
"blueprintIdentifier": "ec2Instance"
},
"invocationMethod": {
"type": "INTEGRATION_ACTION",
"installationId": "<YOUR_GITHUB_OCEAN_INTEGRATION_ID>",
"integrationActionType": "dispatch_workflow",
"integrationActionExecutionProperties": {
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "<GITHUB_WORKFLOW_FILE>",
"workflowInputs": {
"instance_name": "{{ .inputs.\"instance_name\" }}",
"instance_type": "{{ .inputs.\"instance_type\" }}",
"image_id": "{{ .inputs.\"image_id\" }}",
"key_pair_name": "{{ .inputs.\"key_pair_name\" }}",
"security_group_ids": "{{ .inputs.\"security_group_ids\" }}",
"port_context": {
"entity": "{{ .entity }}",
"blueprint": "{{ .action.blueprint }}",
"runId": "{{ .run.id }}",
"trigger": "{{ .trigger }}"
}
},
"reportWorkflowStatus": true
}
},
"requiredApproval": false
}
Create S3 Bucket self-service action
- GitHub (Legacy)
- GitHub (Ocean)
{
"identifier": "create_s3_bucket",
"title": "Create S3 Bucket",
"icon": "S3",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"bucket_name": {
"title": "Bucket Name",
"type": "string",
"minLength": 3,
"maxLength": 63
},
"bucket_acl": {
"icon": "DefaultProperty",
"title": "Bucket ACL",
"description": "bucket access control list",
"type": "string",
"default": "Private",
"enum": [
"Private",
"PublicRead",
"PublicReadWrite",
"AuthenticatedRead"
],
"enumColors": {
"Private": "lightGray",
"PublicRead": "lightGray",
"PublicReadWrite": "lightGray",
"AuthenticatedRead": "lightGray"
}
}
},
"required": ["bucket_name", "bucket_acl"],
"order": ["bucket_name", "bucket_acl"]
},
"blueprintIdentifier": "s3_bucket"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "<GITHUB_WORKFLOW_FILE>",
"workflowInputs": {
"bucket_name": "{{ .inputs.\"bucket_name\" }}",
"bucket_acl": "{{ .inputs.\"bucket_acl\" }}",
"port_context": {
"entity": "{{ .entity }}",
"blueprint": "{{ .action.blueprint }}",
"runId": "{{ .run.id }}",
"trigger": "{{ .trigger }}"
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false
}
{
"identifier": "create_s3_bucket",
"title": "Create S3 Bucket",
"icon": "S3",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"bucket_name": {
"title": "Bucket Name",
"type": "string",
"minLength": 3,
"maxLength": 63
},
"bucket_acl": {
"icon": "DefaultProperty",
"title": "Bucket ACL",
"description": "bucket access control list",
"type": "string",
"default": "Private",
"enum": [
"Private",
"PublicRead",
"PublicReadWrite",
"AuthenticatedRead"
],
"enumColors": {
"Private": "lightGray",
"PublicRead": "lightGray",
"PublicReadWrite": "lightGray",
"AuthenticatedRead": "lightGray"
}
}
},
"required": ["bucket_name", "bucket_acl"],
"order": ["bucket_name", "bucket_acl"]
},
"blueprintIdentifier": "s3_bucket"
},
"invocationMethod": {
"type": "INTEGRATION_ACTION",
"installationId": "<YOUR_GITHUB_OCEAN_INTEGRATION_ID>",
"integrationActionType": "dispatch_workflow",
"integrationActionExecutionProperties": {
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "<GITHUB_WORKFLOW_FILE>",
"workflowInputs": {
"bucket_name": "{{ .inputs.\"bucket_name\" }}",
"bucket_acl": "{{ .inputs.\"bucket_acl\" }}",
"port_context": {
"entity": "{{ .entity }}",
"blueprint": "{{ .action.blueprint }}",
"runId": "{{ .run.id }}",
"trigger": "{{ .trigger }}"
}
},
"reportWorkflowStatus": true
}
},
"requiredApproval": false
}
Deploy RDS Instance self-service action
- GitHub (Legacy)
- GitHub (Ocean)
{
"identifier": "deploy_rds_instance",
"title": "Deploy RDS",
"icon": "AmazonRDS",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"db_instance_identifier": {
"title": "DB Instance Identifier",
"type": "string",
"minLength": 1,
"maxLength": 63
},
"db_master_password": {
"title": "DB Master Password",
"type": "string",
"encryption": "aes256-gcm"
},
"db_master_username": {
"title": "DB Master Username",
"type": "string"
},
"db_engine": {
"title": "DB Engine",
"type": "string",
"default": "mysql",
"enum": ["mysql", "postgres", "sqlserver", "oracle"],
"enumColors": {
"mysql": "lightGray",
"postgres": "lightGray",
"sqlserver": "lightGray",
"oracle": "lightGray"
}
},
"allocated_storage": {
"title": "Allocated Storage",
"type": "number",
"default": 20,
"minimum": 5,
"maximum": 1000
},
"db_instance_class": {
"title": "DB Instance Class",
"type": "string",
"default": "db.t3.micro",
"enum": ["db.t3.micro"],
"enumColors": {
"db.t3.micro": "lightGray"
}
}
},
"required": [
"db_instance_identifier",
"db_master_password",
"db_master_username",
"db_engine",
"allocated_storage",
"db_instance_class"
],
"order": [
"db_instance_identifier",
"db_master_username",
"db_master_password",
"db_engine",
"db_instance_class",
"allocated_storage"
]
},
"blueprintIdentifier": "rds_instance"
},
"invocationMethod": {
"type": "GITHUB",
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "<GITHUB_WORKFLOW_FILE>",
"workflowInputs": {
"db_instance_identifier": "{{.inputs.\"db_instance_identifier\"}}",
"db_master_password": "{{.inputs.\"db_master_password\"}}",
"db_master_username": "{{.inputs.\"db_master_username\"}}",
"db_engine": "{{.inputs.\"db_engine\"}}",
"allocated_storage": "{{.inputs.\"allocated_storage\"}}",
"db_instance_class": "{{.inputs.\"db_instance_class\"}}",
"port_context": {
"entity": "{{ .entity }}",
"blueprint": "{{ .action.blueprint }}",
"runId": "{{ .run.id }}",
"trigger": "{{ .trigger }}"
}
},
"reportWorkflowStatus": true
},
"requiredApproval": false
}
{
"identifier": "deploy_rds_instance",
"title": "Deploy RDS",
"icon": "AmazonRDS",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"db_instance_identifier": {
"title": "DB Instance Identifier",
"type": "string",
"minLength": 1,
"maxLength": 63
},
"db_master_password": {
"title": "DB Master Password",
"type": "string",
"encryption": "aes256-gcm"
},
"db_master_username": {
"title": "DB Master Username",
"type": "string"
},
"db_engine": {
"title": "DB Engine",
"type": "string",
"default": "mysql",
"enum": ["mysql", "postgres", "sqlserver", "oracle"],
"enumColors": {
"mysql": "lightGray",
"postgres": "lightGray",
"sqlserver": "lightGray",
"oracle": "lightGray"
}
},
"allocated_storage": {
"title": "Allocated Storage",
"type": "number",
"default": 20,
"minimum": 5,
"maximum": 1000
},
"db_instance_class": {
"title": "DB Instance Class",
"type": "string",
"default": "db.t3.micro",
"enum": ["db.t3.micro"],
"enumColors": {
"db.t3.micro": "lightGray"
}
}
},
"required": [
"db_instance_identifier",
"db_master_password",
"db_master_username",
"db_engine",
"allocated_storage",
"db_instance_class"
],
"order": [
"db_instance_identifier",
"db_master_username",
"db_master_password",
"db_engine",
"db_instance_class",
"allocated_storage"
]
},
"blueprintIdentifier": "rds_instance"
},
"invocationMethod": {
"type": "INTEGRATION_ACTION",
"installationId": "<YOUR_GITHUB_OCEAN_INTEGRATION_ID>",
"integrationActionType": "dispatch_workflow",
"integrationActionExecutionProperties": {
"org": "<GITHUB_ORG>",
"repo": "<GITHUB_REPO>",
"workflow": "<GITHUB_WORKFLOW_FILE>",
"workflowInputs": {
"db_instance_identifier": "{{.inputs.\"db_instance_identifier\"}}",
"db_master_password": "{{.inputs.\"db_master_password\"}}",
"db_master_username": "{{.inputs.\"db_master_username\"}}",
"db_engine": "{{.inputs.\"db_engine\"}}",
"allocated_storage": "{{.inputs.\"allocated_storage\"}}",
"db_instance_class": "{{.inputs.\"db_instance_class\"}}",
"port_context": {
"entity": "{{ .entity }}",
"blueprint": "{{ .action.blueprint }}",
"runId": "{{ .run.id }}",
"trigger": "{{ .trigger }}"
}
},
"reportWorkflowStatus": true
}
},
"requiredApproval": false
}
- Create a CloudFormation template file in your GitHub repository:
- EC2 Instance
- S3 Bucket
- RDS Instance
AWS CloudFormation Template for EC2 Instance
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation Template to Deploy an EC2 Instance
Parameters:
InstanceName:
Description: Name for the EC2 instance
Type: String
MinLength: 1
MaxLength: 255
Default: MyEC2InstanceName
ConstraintDescription: Instance name must not be empty
InstanceType:
Description: EC2 instance type
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t2.medium
# Add more instance types as needed
ConstraintDescription: Must be a valid EC2 instance type
ImageId:
Description: ID of the Amazon Machine Image (AMI) to use
Type: AWS::EC2::Image::Id
ConstraintDescription: Must be a valid AMI ID
KeyPairName:
Description: Name of the key pair for SSH access
Type: String
MinLength: 1
MaxLength: 255
ConstraintDescription: Key pair name must not be empty
SecurityGroupIds:
Description: List of Security Group IDs for the EC2 instance
Type: List<AWS::EC2::SecurityGroup::Id>
ConstraintDescription: Must be a list of valid Security Group IDs
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref ImageId
KeyName: !Ref KeyPairName
SecurityGroupIds: !Ref SecurityGroupIds
Tags:
- Key: Name
Value: !Ref InstanceName
Outputs:
InstanceId:
Description: ID of the created EC2 instance
Value: !Ref EC2Instance
AWS CloudFormation Template for S3 Bucket
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation Template for an S3 Bucket
Parameters:
BucketName:
Description: Name for the S3 bucket
Type: String
MinLength: 3
MaxLength: 63
ConstraintDescription: The bucket name must be between 3 and 63 characters.
BucketAcl:
Description: Access control for the S3 bucket
Type: String
Default: Private
AllowedValues:
- Private
- PublicRead
- PublicReadWrite
- AuthenticatedRead
ConstraintDescription: Choose a valid access control option.
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Ref BucketName
AccessControl: !Ref BucketAcl
Outputs:
S3BucketName:
Description: Name of the created S3 bucket
Value: !Ref S3Bucket
AWS CloudFormation Template for RDS Instance
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation Template for an Amazon RDS Instance
Parameters:
DBInstanceIdentifier:
Description: Identifier for the RDS instance
Type: String
MinLength: 1
MaxLength: 63
Default: myrdsinstance
ConstraintDescription: The DB instance identifier must be between 1 and 63 characters.
DBMasterUsername:
Description: Master username for the RDS instance
Type: String
MinLength: 1
MaxLength: 63
Default: admin
ConstraintDescription: The master username must be between 1 and 63 characters.
DBMasterPassword:
Description: Master password for the RDS instance
Type: String
NoEcho: true
MinLength: 8
MaxLength: 41
Default: MySecurePassword
ConstraintDescription: The master password must be between 8 and 41 characters.
DBEngine:
Description: Database engine for the RDS instance
Type: String
Default: mysql
AllowedValues:
- mysql
- postgres
- sqlserver
- oracle
ConstraintDescription: Choose a valid database engine.
AllocatedStorage:
Description: Allocated storage for the RDS instance (in GB)
Type: Number
Default: 20
MinValue: 5
MaxValue: 6144
ConstraintDescription: Allocated storage must be between 5 and 6144 GB.
DBInstanceClass:
Description: DB instance class for the RDS instance
Type: String
Default: db.t3.micro
AllowedValues:
- db.t3.micro
# Add more instance types as needed
ConstraintDescription: Choose a valid DB instance class.
Resources:
RDSInstance:
Type: 'AWS::RDS::DBInstance'
Properties:
DBInstanceIdentifier: !Ref DBInstanceIdentifier
AllocatedStorage: !Ref AllocatedStorage
DBInstanceClass: !Ref DBInstanceClass
Engine: !Ref DBEngine
MasterUsername: !Ref DBMasterUsername
MasterUserPassword: !Ref DBMasterPassword
Outputs:
RDSInstanceEndpoint:
Description: Endpoint for the created RDS instance
Value: !GetAtt RDSInstance.Endpoint.Address
- Create a workflow file under
.github/workflows/deploy-cloudformation-template.ymlwith the following content:
Please make sure to modify CF_TEMPLATE_FILE placeholder to match the CloudFormation template file path.
- EC2 Instance
- S3 Bucket
- RDS Instance
GitHub workflow for EC2 Instance
name: Deploy CloudFormation - EC2 Instance
on:
workflow_dispatch:
inputs:
instance_name:
required: true
type: string
description: instance name
instance_type:
required: true
type: string
description: instance type
image_id:
required: true
type: string
description: image id
key_pair_name:
required: true
type: string
description: key pair name
security_group_ids:
required: true
type: string
description: security group ids
port_context:
required: true
description: Action and general port_context (blueprint, run id, etc...)
type: string
jobs:
deploy-cloudformation-template:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS Credentials 🔒
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Deploy to AWS CloudFormation
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
name: ${{ inputs.instance_name }}
template: <CF_TEMPLATE_FILE>
parameter-overrides: >-
InstanceName=${{ inputs.instance_name }},
InstanceType=${{ inputs.instance_type }},
ImageId=${{ inputs.image_id }},
KeyPairName=${{ inputs.key_pair_name }},
SecurityGroupIds="${{ inputs.security_group_ids }}"
- name: UPSERT EC2 Instance Entity in Port
uses: port-labs/port-github-action@v1
with:
identifier: ${{ inputs.instance_name }}
title: ${{ inputs.instance_name }}
team: '[]'
icon: EC2
blueprint: ec2Instance
properties: |-
{
"instance_name": "${{ inputs.instance_name }}",
"instance_type": "${{ inputs.instance_type }}",
"image_id": "${{ inputs.image_id }}",
"key_pair_name": "${{ inputs.key_pair_name }}",
"security_group_ids": "${{ inputs.security_group_ids }}"
}
relations: '{}'
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.port.io
operation: UPSERT
runId: ${{fromJson(inputs.port_context).runId}}
GitHub workflow for S3 Bucket
name: Deploy CloudFormation - S3 Bucket
on:
workflow_dispatch:
inputs:
bucket_name:
required: true
type: string
description: bucket name
bucket_acl:
required: true
type: string
description: bucket acl
port_context:
required: true
description: Details of the action and general port_context (blueprint, run id, etc...)
type: string
jobs:
deploy-cloudformation-template:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS Credentials 🔒
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Deploy to AWS CloudFormation
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
name: ${{ inputs.bucket_name }}
template: <CF_TEMPLATE_FILE>
parameter-overrides: >-
BucketName=${{ inputs.bucket_name }},
BucketAcl=${{ inputs.bucket_acl }}
- name: UPSERT S3 Bucket Entity in Port
uses: port-labs/port-github-action@v1
with:
identifier: ${{ inputs.bucket_name }}
title: ${{ inputs.bucket_name }}
team: '[]'
icon: S3
blueprint: s3_bucket
properties: |-
{
"bucket_name": "${{ inputs.bucket_name }}",
"bucket_acl": "${{ inputs.bucket_acl }}"
}
relations: '{}'
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.port.io
operation: UPSERT
runId: ${{fromJson(inputs.port_context).runId}}
GitHub workflow for RDS Instance
name: Deploy CloudFormation - RDS Instance
on:
workflow_dispatch:
inputs:
db_instance_identifier:
required: true
type: string
description: db_instance_identifier
db_master_username:
required: true
type: string
description: db_master_username
db_master_password:
required: true
type: string
description: db_master_password
db_engine:
required: true
type: string
description: db_engine
db_instance_class:
required: true
type: string
description: db_instance_class
allocated_storage:
required: true
type: number
description: allocated_storage
port_context:
required: true
description: Details about the action and general port_context (blueprint, run id, etc...)
type: string
jobs:
deploy-cloudformation-template:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set Up Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Configure AWS Credentials 🔒
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Decrypt aes256-gcm String
id: decrypt_password
run: |
pip install --upgrade pip
pip install pycryptodome
python decrypt_password.py
env:
PORT_CLIENT_SECRET: ${{ secrets.PORT_CLIENT_SECRET }}
PASSWORD: ${{ inputs.db_master_password }}
- name: Deploy to AWS CloudFormation
uses: aws-actions/aws-cloudformation-github-deploy@v1
with:
name: ${{ inputs.db_instance_identifier }}
template: <CF_TEMPLATE_FILE>
parameter-overrides: >-
DBInstanceIdentifier=${{ inputs.db_instance_identifier }},
DBMasterUsername=${{ inputs.db_master_username }},
DBMasterPassword=${{ steps.decrypt_password.outputs.decrypted_value }},
DBEngine=${{ inputs.db_engine }},
DBInstanceClass=${{ inputs.db_instance_class}},
AllocatedStorage=${{ inputs.allocated_storage }}
- name: UPSERT RDS Instance Entity in Port
uses: port-labs/port-github-action@v1
with:
identifier: ${{ inputs.db_instance_identifier }}
title: ${{ inputs.db_instance_identifier }}
team: '[]'
icon: RDS
blueprint: rds_instance
properties: |-
{
"db_instance_identifier": "${{ inputs.db_instance_identifier }}",
"db_master_username": "${{ inputs.db_master_username }}",
"db_master_password": "${{ inputs.db_master_password }}",
"db_engine": "${{ inputs.db_engine }}",
"db_instance_class": "${{ inputs.db_instance_class }}",
"allocated_storage": ${{ inputs.allocated_storage }}
}
relations: '{}'
clientId: ${{ secrets.PORT_CLIENT_ID }}
clientSecret: ${{ secrets.PORT_CLIENT_SECRET }}
baseUrl: https://api.port.io
operation: UPSERT
runId: ${{fromJson(inputs.port_context).runId}}
Create decrypt_password.py file with the following content to decrypt the password values:Decrypt Password Script
import base64
import os
from Crypto.Cipher import AES
key = os.getenv('PORT_CLIENT_SECRET')[:32].encode()
encrypted_property_value = base64.b64decode(os.getenv('PASSWORD'))
iv = encrypted_property_value[:16]
ciphertext = encrypted_property_value[16:-16]
mac = encrypted_property_value[-16:]
cipher = AES.new(key, AES.MODE_GCM, iv)
# decrypt the property
decrypted_property_value = cipher.decrypt_and_verify(ciphertext, mac)
print(f"::set-output name=decrypted_value::{decrypted_property_value}")
- Trigger the action from the Self-service tab of your Port application.
What's next?
- Connect Port's AWS exporter to make sure all of the properties and entities are automatically ingested from AWS.