Skip to content

Commit

Permalink
test monorepo
Browse files Browse the repository at this point in the history
  • Loading branch information
Resonance1584 committed May 14, 2024
1 parent 03da8fb commit f30681d
Show file tree
Hide file tree
Showing 21 changed files with 2,202 additions and 1 deletion.
103 changes: 103 additions & 0 deletions .github/actions/pipelines-aws-execute/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Terragrunt AWS Execute
description: "Authenticates to AWS then invokes terragrunt"
inputs:
PIPELINES_READ_TOKEN:
description: "The PIPELINES_READ_TOKEN secret"
required: true
working_directory:
description: ""
required: true
account_id:
description: ""
required: true
account_role_name:
description: ""
required: true
role_session_name:
description: ""
required: true
gruntwork_context:
description: ""
required: true


outputs:
execute_stdout:
description: "The output of the Pipelines Execute command"
value: ${{ steps.execute.outputs.execute_stdout }}
plan_folder:
description: "A folder with plan files (if any)"
value: ${{ steps.execute.outputs.plan_folder }}
formatted_plan_output:
description: "A string, formatted in GitHub Markdown, rendering human readable output of the plan"
value: ${{ steps.execute.outputs.formatted_plan_output }}

runs:
using: composite
steps:
- name: "Read in Gruntwork context"
id: gruntwork_context
uses: gruntwork-io/[email protected]
with:
cache: ${{ inputs.gruntwork_context }}

- name: Authenticate to AWS
id: aws_auth
uses: aws-actions/configure-aws-credentials@v4
with:
# We can authenticate to any valid region, the IaC configured provider determines what region resources are created
# in. As a result we can pass the default aws region.
aws-region: ${{ steps.gruntwork_context.outputs.default_aws_region }}
role-to-assume: "arn:aws:iam::${{ inputs.account_id }}:role/${{ inputs.account_role_name }}"
role-duration-seconds: 3600
role-session-name: ${{ inputs.role_session_name }}

- name: "Get Auth Failure Reason"
shell: bash
id: auth_failure_reason
if: ${{ failure() }}
env:
ACCOUNT_ID: ${{ inputs.account_id }}
ACCOUNT_ROLE_NAME: ${{ inputs.account_role_name }}
run: |
# if the role_name begins with 'delegate' the role may not have been created yet
if [[ $ACCOUNT_ROLE_NAME == delegate* ]]; then
reason="Failed to authenticate to AWS. The role($ACCOUNT_ROLE_NAME) may not have been created yet. Contact your account administrator to ensure that access-control Pull Request for this account($ACCOUNT_ID) has been merged."
else
reason="Failed to authenticate to AWS. Verify that the role($ACCOUNT_ROLE_NAME) and account ID($ACCOUNT_ID) are correct."
fi
echo "auth_failure_reason=$reason" >> $GITHUB_OUTPUT
- name: "Add Auth Failure Notice if AWS Auth Fails"
uses: gruntwork-io/[email protected]
if: ${{ failure() }}
with:
step_name: "AWS Authentication"
step_status: "failed"
step_details: ${{ steps.auth_failure_reason.outputs.auth_failure_reason }}
pull_request_number: ${{ steps.gruntwork_context.outputs.pr_number }}

- name: "[Terragrunt Execute] Confirm Account Access"
if: ${{ steps.aws_auth.outcome == 'success' }}
shell: bash
env:
ACCOUNT: ${{ inputs.account_id }}
WORKING_DIRECTORY: ${{ inputs.working_directory }}
run: echo "::notice ::Running in account $ACCOUNT and planning in $WORKING_DIRECTORY"

- name: "[Terragrunt Execute] Run terragrunt ${{ inputs.terragrunt_command }} in ${{ inputs.working_directory }}"
if: ${{ steps.aws_auth.outcome == 'success' }}
id: execute
uses: gruntwork-io/[email protected]
with:
token: ${{ inputs.PIPELINES_READ_TOKEN }}
tf_binary: ${{ steps.gruntwork_context.outputs.tf_binary }}
working_directory: ${{ inputs.working_directory }}
pipelines_cli_version: ${{ steps.gruntwork_context.outputs.pipelines_cli_version }}
terragrunt_command: ${{ steps.gruntwork_context.outputs.terragrunt_command }}
infra_live_repo_branch: ${{ steps.gruntwork_context.outputs.branch }}
gruntwork_config_file: ${{ steps.gruntwork_context.outputs.gruntwork_config_file }}
infra_live_repo: "."
infra_live_directory: "."
deploy_branch_name: ${{ steps.gruntwork_context.outputs.deploy_branch_name }}
60 changes: 60 additions & 0 deletions .github/actions/pipelines-baseline-account-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Bootstrap a new account in access-control repo
description: "Sets up a new AWS account and basic roles inside the access control repo"
inputs:
PIPELINES_READ_TOKEN:
description: "The PIPELINES_READ_TOKEN secret"
required: true
gruntwork_context:
description: "Gruntwork Context from the Gruntwork Bootstrap step"
required: true

runs:
using: composite
steps:
- name: "[Baseline]: Read account request"
id: gruntwork_context
uses: gruntwork-io/[email protected]
with:
cache: ${{ inputs.gruntwork_context }}

- name: "[Baseline]: Run terragrunt ${{ steps.gruntwork_context.outputs.terragrunt_command }} in security account"
id: terragrunt-apply-security
uses: gruntwork-io/[email protected]
with:
PIPELINES_READ_TOKEN: ${{ inputs.PIPELINES_READ_TOKEN }}
account_id: ${{ steps.gruntwork_context.outputs.security_account_id }}
account_role_name: ${{ steps.gruntwork_context.outputs.role_name }}
role_session_name: ${{ steps.gruntwork_context.outputs.role_session_name }}
working_directory: security/_global/account-baseline
gruntwork_context: ${{ inputs.gruntwork_context }}

- name: "[Baseline]: Run terragrunt ${{ steps.gruntwork_context.outputs.terragrunt_command }} in logs account"
id: terragrunt-apply-logs
uses: gruntwork-io/[email protected]
with:
PIPELINES_READ_TOKEN: ${{ inputs.PIPELINES_READ_TOKEN }}
account_id: ${{ steps.gruntwork_context.outputs.logs_account_id }}
account_role_name: ${{ steps.gruntwork_context.outputs.role_name }}
role_session_name: ${{ steps.gruntwork_context.outputs.role_session_name }}
working_directory: logs/_global/account-baseline
gruntwork_context: ${{ inputs.gruntwork_context }}

- name: "[Baseline]: Run terragrunt ${{ steps.gruntwork_context.outputs.terragrunt_command }} in shared account"
id: terragrunt-apply-shared
uses: gruntwork-io/[email protected]
with:
PIPELINES_READ_TOKEN: ${{ inputs.PIPELINES_READ_TOKEN }}
account_id: ${{ steps.gruntwork_context.outputs.shared_account_id }}
account_role_name: ${{ steps.gruntwork_context.outputs.role_name }}
role_session_name: ${{ steps.gruntwork_context.outputs.role_session_name }}
working_directory: shared/_global/account-baseline
gruntwork_context: ${{ inputs.gruntwork_context }}

# Finally, auth to the mgmt account so we can assume a role in the child account
- name: "[Baseline]: Authenticate to AWS"
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ steps.gruntwork_context.outputs.default_aws_region }}
role-to-assume: "arn:aws:iam::${{ steps.gruntwork_context.outputs.account_id }}:role/${{ steps.gruntwork_context.outputs.role_name }}"
role-duration-seconds: 3600
role-session-name: ${{ steps.gruntwork_context.outputs.role_session_name }}
115 changes: 115 additions & 0 deletions .github/actions/pipelines-baseline-child-account-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Bootstrap Workflow
description: "Bootstrap workflows with common requirements"
inputs:
PIPELINES_READ_TOKEN:
description: "The GitHub token to use for checking out the infrastructure-live repo"
required: true
account_id:
description: "Child Account ID to operate on"
required: true
account_name:
description: "Child Account Name to operate on"
required: true
job:
description: "JSON of pipelines orchestrate job"
required: true

runs:
using: composite
steps:
- name: Check out repo code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Bootstrap Workflow
id: gruntwork_context
uses: gruntwork-io/[email protected]
with:
token: ${{ inputs.PIPELINES_READ_TOKEN }}
change_type: ${{ fromJson(inputs.job).ChangeType }}
branch: ${{ fromJson(inputs.job).Ref }}
working_directory: ${{ fromJson(inputs.job).WorkingDirectory }}
account_id: ${{ fromJson(inputs.job).AccountId }}
terragrunt_command: ${{ fromJson(inputs.job).Action.Command }} ${{ fromJson(inputs.job).Action.Args }}
additional_data: ${{ toJson(fromJson(inputs.job).AdditionalData) }}
account_names: ${{ fromJson(inputs.job).AdditionalData.AccountNames }}
child_account_id: ${{ inputs.account_id }}
new_account_name: ${{ inputs.account_name }}

# Finally, auth to the mgmt account so we can assume a role in the child account
- name: "[Baseline]: Authenticate to AWS"
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ steps.gruntwork_context.outputs.default_aws_region }}
role-to-assume: "arn:aws:iam::${{ steps.gruntwork_context.outputs.account_id }}:role/${{ steps.gruntwork_context.outputs.role_name }}"
role-duration-seconds: 3600
role-session-name: ${{ steps.gruntwork_context.outputs.role_session_name }}

# Auth to child account
# THIS RETRIEVES PERMISSIONS TO BE ABLE TO RUN A PLAN/APPLY IN THE NEWLY CREATED CHILD ACCOUNT
# The "AWSControlTowerExecution" role being assumed here is created by Control Tower in each account it provisions
# and it can be assumed by a role in the management account.
- name: "[Baseline]: Assume role new child account"
shell: bash
env:
SESSION_NAME: ${{ steps.gruntwork_context.outputs.role_session_name }}
CHILD_ACCOUNT_ID: ${{ inputs.account_id }}
run: |
echo "Assuming AWSControlTowerExecution Role -- arn:aws:iam::$CHILD_ACCOUNT_ID:role/AWSControlTowerExecution"
RESPONSE="$(aws sts assume-role --role-arn "arn:aws:iam::$CHILD_ACCOUNT_ID:role/AWSControlTowerExecution" --role-session-name "$SESSION_NAME")"
ASSUMED_ROLE_CREDS="$(echo "$RESPONSE" | jq -r '.Credentials')"
AWS_ACCESS_KEY_ID="$(echo "$ASSUMED_ROLE_CREDS" | jq -r '.AccessKeyId')"
echo "AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> "$GITHUB_ENV"
echo "::add-mask::$AWS_ACCESS_KEY_ID"
AWS_SECRET_ACCESS_KEY="$(echo "$ASSUMED_ROLE_CREDS" | jq -r '.SecretAccessKey')"
echo AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" >> "$GITHUB_ENV"
echo "::add-mask::$AWS_SECRET_ACCESS_KEY"
AWS_SESSION_TOKEN="$(echo "$ASSUMED_ROLE_CREDS" | jq -r '.SessionToken')"
echo AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN" >> "$GITHUB_ENV"
echo "::add-mask::$AWS_SESSION_TOKEN"
- name: "[Baseline]: Confirm Account Access"
shell: bash
run: aws sts get-caller-identity

# This Bootstrap step is a workaround for the error that happens when running plan-all for the first time in a
# new account with multiple modules. The error is:
#
# OperationAborted: A conflicting conditional operation is currently in progress against this resource. Please try again.
# BucketAlreadyOwnedByYou: Your previous request to create the named bucket succeeded and you already own it.
#
# This happens because each module is trying to create buckets for state and logs when they do not exist.
# Setting Terragrunt Parallelism to 1 does NOT prevent this error from happening. So we'll instead run an init in
# a single module first to create the buckets so that subsequent run-all commands do not fail.
- name: "[Baseline]: Bootstrap child account with state & logs S3 buckets"
if: ${{ contains(steps.gruntwork_context.outputs.terragrunt_command, 'plan') }}
uses: gruntwork-io/[email protected]
with:
token: ${{ inputs.PIPELINES_READ_TOKEN }}
pipelines_cli_version: ${{ steps.gruntwork_context.outputs.pipelines_cli_version }}
working_directory: "${{ inputs.account_name }}/_global/account-baseline"
terragrunt_command: "init"
infra_live_repo: '.'
infra_live_directory: '.'
infra_live_repo_branch: ${{ steps.gruntwork_context.outputs.branch }}
gruntwork_config: "${{ steps.gruntwork_context.outputs.gruntwork_config }}"
gruntwork_config_file: "${{ steps.gruntwork_context.outputs.gruntwork_config_file }}"
deploy_branch_name: ${{ steps.gruntwork_context.outputs.deploy_branch_name }}
tf_binary: ${{ steps.gruntwork_context.outputs.tf_binary }}

# Apply Access Control Roles and Baseline in Delegated Account
- name: "[Baseline]: Bootstrap child account with access control roles, state & logs S3 buckets"
uses: gruntwork-io/[email protected]
with:
token: ${{ inputs.PIPELINES_READ_TOKEN }}
pipelines_cli_version: ${{ steps.gruntwork_context.outputs.pipelines_cli_version }}
working_directory: "${{ inputs.account_name }}"
terragrunt_command: ${{ steps.gruntwork_context.outputs.terragrunt_command }}
infra_live_repo: '.'
infra_live_directory: '.'
infra_live_repo_branch: ${{ steps.gruntwork_context.outputs.branch }}
gruntwork_config: "${{ steps.gruntwork_context.outputs.gruntwork_config }}"
gruntwork_config_file: "${{ steps.gruntwork_context.outputs.gruntwork_config_file }}"
deploy_branch_name: ${{ steps.gruntwork_context.outputs.deploy_branch_name }}
tf_binary: ${{ steps.gruntwork_context.outputs.tf_binary }}
Empty file.
Loading

0 comments on commit f30681d

Please sign in to comment.