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.