Automate AWS Account Creation with GitLab
Overviewโ
This guide demonstrates how to implement a self-service action in Port to automates the creation of new AWS accounts and associated resources using GitLab CI/CD and Terraform.
Common use casesโ
- Multi-account strategy: Enable teams to quickly spin up dedicated AWS accounts for different projects or environments.
 - Development environments: Provide developers with isolated AWS accounts for testing and development.
 - Client onboarding: Streamline the process of creating dedicated AWS accounts for new clients or business units.
 - Compliance and security: Maintain standardized account configurations with proper IAM roles and policies.
 - Cost management: Enable better cost tracking and resource isolation through dedicated accounts.
 
Prerequisitesโ
This guide assumes you have:
- Complete the onboarding process.
 - A GitLab account with a repository set up for CI/CD.
 - AWS Organizations access with permissions to create new accounts.
 - AWS IAM permissions for Terraform operations.
 - Port's AWS integration is installed in your account.
 - Port Client ID and Client Secret (learn more).
 
Set up data modelโ
We'll create a blueprint to represent AWS accounts in your Port catalog.
Create the AWS Account blueprintโ
- 
Go to the Builder page of your portal.
 - 
Click on
+ Blueprint. - 
Click on the
{...}button in the top right corner, and chooseEdit JSON. - 
Add this JSON schema:
AWS Account blueprint (Click to expand)
{
"identifier": "awsAccountBlueprint",
"description": "This blueprint represents an AWS account in our software catalog.",
"title": "AWS account",
"icon": "AWS",
"schema": {
"properties": {
"role_name": {
"type": "string",
"title": "Role Name",
"description": "The name of the IAM role."
},
"account_name": {
"type": "string",
"title": "Account Name",
"description": "The name for the account."
},
"email": {
"type": "string",
"title": "Email",
"description": "The email for the account."
}
},
"required": [
"email",
"account_name"
]
},
"relations": {}
} - 
Click
Saveto create the blueprint. 
Implementationโ
Add GitLab secretsโ
In your GitLab project, go to Settings > CI/CD > Variables and add the following variables:
PORT_CLIENT_ID- Port Client ID learn more.PORT_CLIENT_SECRET- Port Client Secret learn more.TF_USER_AWS_KEY- AWS Access Key ID with Organizations permissions.TF_USER_AWS_SECRET- AWS Secret Access Key.TF_USER_AWS_REGION- AWS region for resource creation (e.g.,us-east-1).
Set up Terraform configurationโ
Create the following Terraform files in your GitLab repository to define the AWS account creation infrastructure.
Main Terraform configuration
Create main.tf:
Terraform main configuration (Click to expand)
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}
provider "aws" {
  region = var.region
}
resource "aws_organizations_account" "account" {
  name      = var.name
  email     = var.email
  role_name = var.role_name
  close_on_deletion = true
  
  lifecycle {
    ignore_changes = [role_name]
  }
}
Create Terraform variables
Create variables.tf:
Terraform variables configuration (Click to expand)
variable "region" {
  description = "AWS region where resources will be created"
  type        = string
  default     = "us-east-1"
}
variable "name" {
  description = "Name of the AWS account to be created"
  type        = string
  default     = "newAccount"
}
variable "email" {
  description = "Email to attach to the AWS account"
  type        = string
  default     = "example@example.com"
}
variable "role_name" {
  description = "Name of the IAM role to attach"
  type        = string
  default     = "IAMRole"
}
Create Terraform outputs
Create outputs.tf:
Terraform outputs configuration (Click to expand)
output "account_name" {
  value = aws_organizations_account.account.name
}
output "email" {
  value = aws_organizations_account.account.email
}
output "role_name" {
  value = aws_organizations_account.account.role_name
}
Add GitLab pipelineโ
Create .gitlab-ci.yml in your repository:
GitLab CI/CD pipeline (Click to expand)
stages:
  - prerequisites
  - terraform
  - port-update
image:
  name: hashicorp/terraform:light
  entrypoint:
    - '/usr/bin/env'
    - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
variables:
  AWS_ACCESS_KEY_ID: ${TF_USER_AWS_KEY}
  AWS_SECRET_ACCESS_KEY : ${TF_USER_AWS_SECRET}
  AWS_DEFAULT_REGION: ${TF_USER_AWS_REGION}
  PORT_CLIENT_ID: ${PORT_CLIENT_ID}
  PORT_CLIENT_SECRET: ${PORT_CLIENT_SECRET}
before_script:
  - rm -rf .terraform
  - export AWS_ACCESS_KEY=${AWS_ACCESS_KEY_ID}
  - export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
  - export AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}
  - apk update
  - apk add --upgrade curl jq -q
fetch-port-access-token:
  stage: prerequisites
  except:
    - pushes
  script:
    - |
      echo "Getting access token from Port API"
      accessToken=$(curl -X POST \
        -H 'Content-Type: application/json' \
        -d '{"clientId": "'"$PORT_CLIENT_ID"'", "clientSecret": "'"$PORT_CLIENT_SECRET"'"}' \
        -s 'https://api.getport.io/v1/auth/access_token' | jq -r '.accessToken')
    
      echo "ACCESS_TOKEN=$accessToken" >> data.env
      cat $TRIGGER_PAYLOAD 
      runId=$(cat $TRIGGER_PAYLOAD | jq -r '.RUN_ID')
      ACCOUNT_NAME=$(cat $TRIGGER_PAYLOAD | jq -r '.account_name')
      EMAIL=$(cat $TRIGGER_PAYLOAD | jq -r '.email')
      IAM_ROLE_NAME=$(cat $TRIGGER_PAYLOAD | jq -r '.role_name')
      echo "RUN_ID=$runId" >> data.env
      echo "ACCOUNT_NAME=$ACCOUNT_NAME" >> data.env
      echo "EMAIL=$EMAIL" >> data.env
      echo "IAM_ROLE_NAME=$IAM_ROLE_NAME" >> data.env
      curl -X POST \
        -H 'Content-Type: application/json' \
        -H "Authorization: Bearer $accessToken" \
        -d '{"message":"๐โโ๏ธ Starting action to create an AWS account"}' \
        "https://api.getport.io/v1/actions/runs/$runId/logs"
      curl -X PATCH \
        -H 'Content-Type: application/json' \
        -H "Authorization: Bearer $accessToken" \
        -d '{"link":"'"$CI_PIPELINE_URL"'"}' \
        "https://api.getport.io/v1/actions/runs/$runId"
  artifacts:
    reports:
      dotenv: data.env
create-aws-account:
  stage: terraform
  needs:
    - job: fetch-port-access-token
      artifacts: true
  script:
    - echo "Creating AWS account and IAM role..."
    - terraform init
    - terraform apply -auto-approve -var "account_name=${ACCOUNT_NAME}" -var "email=${EMAIL}" -var "iam_role_name=${IAM_ROLE_NAME}"
send-data-to-port:
  stage: port-update
  dependencies:
    - fetch-port-access-token
  script:
    - |
      curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $ACCESS_TOKEN" \
        -d "{\"identifier\": \"${EMAIL}\", \
             \"title\": \"${ACCOUNT_NAME}\", \
             \"properties\": { \
               \"account_name\": \"${ACCOUNT_NAME}\", \
               \"email\": \"${EMAIL}\", \
               \"iam_role_name\": \"${IAM_ROLE_NAME}\", \
               \"additional_data\": \"Your additional data here\" \
             }, \
             \"relations\": {}}" \
        "https://api.getport.io/v1/blueprints/awsAccountBlueprint/entities?run_id=$RUN_ID"
      
      curl -X PATCH \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $ACCESS_TOKEN" \
        -d '{"status": "SUCCESS", "message": {"run_status": "Run completed successfully!"}}' \
        "https://api.getport.io/v1/actions/runs/$RUN_ID"
Configure GitLab webhookโ
- 
In your GitLab project, go to Settings > CI/CD > Pipeline trigger tokens.
 - 
Click Add trigger token to create a new token.
 - 
Copy the webhook URL from the Use webhook section under View trigger token usage examples.
 - 
Keep this URL for the next step - you'll need it for the Port self-service action.
 
Set up self-service actionโ
Now we'll create a self-service action that triggers the AWS account creation workflow.
- 
Head to the self-service page.
 - 
Click on the
+ New Actionbutton. - 
Click on the
{...} Edit JSONbutton. - 
Copy and paste the following JSON configuration into the editor.
GitLab webhook configurationMake sure to replace
WEBHOOK-URL-FROM-GITLABwith the actual webhook URL you obtained from GitLab in the previous step.Create AWS Account action (Click to expand)
{
"identifier": "gitlabAwsAccountBlueprint_create_an_aws_account",
"title": "Create An AWS Account with GitLab",
"icon": "AWS",
"description": "Automate the creation of a new AWS account and associated resources.",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"account_name": {
"icon": "AWS",
"title": "Account Name",
"description": "The desired name for the new AWS account",
"type": "string"
},
"email": {
"icon": "DefaultProperty",
"title": "Email",
"description": "The email address associated with the new AWS account",
"type": "string",
"pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
},
"iam_role_name": {
"title": "IAM Role Name",
"description": "The name of the IAM role to be created for management purposes",
"type": "string"
}
},
"required": [
"account_name",
"email"
],
"order": [
"account_name",
"email",
"iam_role_name"
]
},
"blueprintIdentifier": "awsAccountBlueprint"
},
"invocationMethod": {
"type": "WEBHOOK",
"url": "WEBHOOK-URL-FROM-GITLAB",
"method": "POST",
"headers": {
"RUN_ID": "{{ .run.id }}"
},
"body": {
"RUN_ID": "{{ .run.id }}",
"account_name": "{{ .inputs.\"account_name\" }}",
"email": "{{ .inputs.\"email\" }}",
"iam_role_name": "{{ .inputs.\"iam_role_name\" }}"
}
},
"requiredApproval": false
} - 
Click
Save. 
Now you should see the Create An AWS Account with GitLab action in the self-service page. ๐
Let's test it!โ
- 
Head to the self-service page of your portal
 - 
Click on the
Create An AWS Account with GitLabaction - 
Fill in the account details:
- Account Name: Enter a descriptive name for your new AWS account.
 - Email: Provide a unique email address (must be different from existing AWS accounts).
 - IAM Role Name: Specify the name for the IAM role (optional).
 
 - 
Click on
Execute - 
Monitor the process:
- Watch the GitLab pipeline execution through the provided link.
 - Check the logs in Port for real-time updates.
 - Verify Terraform operations in the GitLab CI/CD pipeline.
 
 - 
Verify completion:
- Check that a new AWS account entity appears in your Port catalog.
 - Verify the account was created in your AWS Organizations console.
 - Confirm all properties are correctly populated in the Port entity.
 
 
Conclusionโ
By following these steps, you can automate the creation of new AWS accounts using GitLab CI/CD and Port self-service actions.