Skip to content

0.3.0

Choose a tag to compare

@jchrisfarris jchrisfarris released this 20 Jun 13:38
· 2 commits to latest since this release
Immutable release. Only release title and notes can be modified.

New Features

  • Add a generic CloudFormation Stackset Capability
  • Add payer_cloudformation_stacks and security_account_stacks to deploy arbitrary CloudFormation stacks into the payer and security accounts directly from Terraform. Each is a map keyed by an HCL identifier and expanded across optional regions (composite addresses like aws_cloudformation_stack.payer["billing_alerts-us-east-1"] so adding a region later doesn't rename existing stacks). Templates come from a local template_file (relative to path.root) or an HTTPS/S3 template_url — exactly one is required.
  • Optionally manage the Terraform state bucket. With manage_state_bucket = true (the default), org-kickstart adopts the existing backend_bucket — via an import block in the calling module (Terraform ignores import blocks inside child modules), see examples/local-deploy/import.tf — and enforces versioning, public-access-block, and AES256 encryption on it. The bucket has prevent_destroy set so Terraform will never delete it. Set manage_state_bucket = false to leave the bucket unmanaged.
  • examples/local-deploy/import.tf adopts the three foundational resources (the AWS Organization, the payer account, and the state bucket) declaratively via import blocks, using data.aws_organizations_organization for the org and payer IDs. A brand-new org no longer needs to run scripts/import_org.sh for these — that script is now only required to adopt an existing org's accounts, OUs, and policies.
  • Account attribute allows you to specify which AWS Organizations services the account is Delegated Admin for
  • Add Organizational Budget support
  • Add individual account budget support
  • Add a (required) security_account block to hold settings for the security account. This gives the security account configuration feature parity with all the other accounts.
  • Add the ability to set the close-on-deletion setting for when an account is removed from the org.
  • Add optional support for DataTrails PR14
  • The Security Account is made the delegated administrator for Personal Health Dashboard - it will receive PHD events from all accounts in the organization
  • Ability to control stackset delegation to the security account. Thanks Ashex!
  • Ability to explicitly exclude certian aws_service_access_principals and enabled_policy_types, via aws_service_access_principals_to_exclude and organization_policy_types_to_exclude Thanks Ashex!
  • New script to generate a granted config from the output of the account list.

Major Breaking Change

  • The Security Account is no longer default assigned as Delegated Admin for IAM Identity Center (sso).
  • A security account block is now required in the tfvars file. SSO Delegated Admin can be applied here if needed.

Minor Updates

  • New EC2 Image Declarative policy to limit AMIs to only AWS & Marketplace
    • WARNING: This may prevent org-shared AMI Launchings. Caveat Emptor
    • Added EC2ImageSnapshotBPA_ALLOW_DCP.json declarative policy to override the Block of AMIs & Snapshots
  • Improved Variable and Validations - Thanks skwashd
  • Fixing a number of things flagged by Checkov:
    1. Added a aws_s3_bucket_public_access_block to the billing_logs bucket
    2. configure AWS KMS on the cloudtrail_s3_notification_topic and billing_alerts SNS Topics
    3. Fixed the block public access setting on VPC FlowLogs to restrict_public_buckets
  • Output Account Listing - Thanks skwashd
  • Enable User Notification service for Trusted access (Note: tf provider support doens't yet exist to configure this service.)
  • Account OUs can now be specified by both OU Name and OU ID.
  • examples/local-deploy gained an account-configurator Make target that pulls in the pht-account-configurator submodule, seeds <env>-account-config.yaml from the sample if missing, packages the CloudFormation template into the state bucket, and deterministically rewrites the account_configurator stanza in <env>.tfvars (removing any stale or commented-out copy) so template / account_factory_config_file point at the freshly packaged template and config — then make tf-apply deploys it. See the Account Configurator docs.
  • examples/local-deploy README trimmed to a concise day-to-day operations guide that points to aws-kickstart.org for full docs, setup, and bootstrap steps; .gitignore synced with the reference deployment.
  • Added examples/local-deploy as the sample layout for running Org Kickstart from a workstation (the Makefile flow); it is now the canonical sample referenced by the docs. (examples/pipeline is retained for in-progress CI/CD tooling.)
  • README slimmed to a project overview that links to aws-kickstart.org for full docs, with release/versioning info at the top; Future Work moved to TODO.md.

Minor Breaking Change

  • PR#9 changed how the SCP attachments are named, rather than being based on count, they are based on foreach. This means that the SCP/RCP/DP attachments will be destroyed and recreated as such

    # module.organization.module.scp["deny_root"].aws_organizations_policy_attachment.scp_attachment[0] will be destroyed
    # (because resource does not use count)
    - resource "aws_organizations_policy_attachment" "scp_attachment" {
        - id        = "r-xxxx:p-yyyyy" -> null
        - policy_id = "p-yyyyy" -> null
        - target_id = "r-xxxx" -> null
        }
    
    # module.organization.module.scp["deny_root"].aws_organizations_policy_attachment.scp_attachment["Root"] will be created
    + resource "aws_organizations_policy_attachment" "scp_attachment" {
        + id        = (known after apply)
        + policy_id = "p-yyyyy"
        + target_id = "r-xxxx"
        }
    

    This is a cleaner way to handle the attachments, and won't risk further unexpected changes if the list of attachment OUs change and a reindex occurs.

  • The SCP/RCP/Decalaritive Policies have been refactored into a single module for any form or Organizational Policy. This caused resource renaming to occur. So in addition to the Policy attachments changing, the policies themselves will be renamed. You can preserve them via terraform state mv like so:

    terraform state mv 'module.organization.module.scp["deny_root"].aws_organizations_policy.scp' 'module.organization.module.scp["deny_root"].aws_organizations_policy.org_policy'

    Otherwise they'll be recreated.

Bug Fixes

  • Added explicit depends_on to several Organizations resources that previously raced creation on a first apply:
    • The AI opt-out policy (aws_organizations_policy.ai_policy), RAM organization sharing (aws_ram_sharing_with_organization.enable), and the SCP / RCP / Declarative policy modules now depend on aws_organizations_organization.org. These resources only referenced the org indirectly (through a separate policy attachment), so Terraform could create them before the org existed, producing AWSOrganizationsNotInUseException ("Your account is not a member of an organization") errors.
    • The CUR report definition (aws_cur_report_definition.cur_report_definition) now depends on the billing bucket policy (aws_s3_bucket_policy.allow_billing_logging) so CUR's create-time bucket-permission check doesn't run before the policy is in place.
  • Marked the granted Makefile target .PHONY so make env=<env> granted runs even when a granted/ directory exists (Make previously reported granted is up to date and skipped the script).
  • The granted Makefile target now writes its output to granted/aws-config (creating the directory if needed) instead of stdout, so it populates the path the sample granted.yml references for use as a Granted Registry.

Known Bugs

  1. You can't use the parent_ou_name for OUs that are not direct descendants of the Root OU

Migrating Security Services from Region Based Providers to Region Variable.

With the introduction of the region variable in the 6.x version of the AWS Provider, the need for the generate_regions.sh script has gone away. If you were managing security services via the dedicated providers for payer and security account, you will need to tell terraform to "move" them to the new resource locations.

This migration script should handle generating the moved resources:

#!/bin/bash

> moves.tf
REGIONS=`aws ec2 describe-regions  | jq -r '.Regions[].RegionName'`

for r in $REGIONS ; do
  cat <<EOF >> moves.tf

# $r
moved {
    from = module.security-services-$r.aws_guardduty_detector.payer_detector[0]
    to = module.organization.module.security-services["$r"].aws_guardduty_detector.payer_detector[0]
}
moved {
    from = module.security-services-$r.aws_guardduty_detector.security_detector[0]
    to = module.organization.module.security-services["$r"].aws_guardduty_detector.security_detector[0]
}
moved {
    from = module.security-services-$r.aws_guardduty_organization_admin_account.guardduty[0]
    to = module.organization.module.security-services["$r"].aws_guardduty_organization_admin_account.guardduty[0]
}
moved {
    from =  module.security-services-$r.aws_guardduty_organization_configuration.organization[0]
    to = module.organization.module.security-services["$r"].aws_guardduty_organization_configuration.organization[0]
}
EOF

done