Skip to content

Releases

pdc-tf-modules v1.0.0

Choose a tag to compare

@jordanpadams jordanpadams released this 30 Oct 14:21
152417c

First tagged release of the PDC Terraform modules. It captures the module set used by the o11y platform stack and lets consumers pin to a version instead of tracking main.

⚠️ Breaking Changes

If you consume these modules from an unpinned ref, review the items below before adopting v1.0.0.

  • EC2 module manages instances directly; the launch template is removed. Affects every ec2 module caller.
    Existing instances are replaced on the next apply (outage, new instance ID and host keys). The old root volume is orphaned unless root_volume_delete_on_termination = true. Outputs change from lists to maps keyed by instance_name, and settings the template used to hide (such as iam_instance_profile) now show as plan drift.
    How to migrate:

    1. Pin a ref until you have a maintenance window.
    2. Replace ec2_instance_id[0] with instance_ids["<name>"]; likewise public_ips and private_ips.
    3. To adopt an instance without replacing it (untested, try in dev first):
      terraform state rm 'module.ec2.aws_instance.pds_ec2[0]'
      terraform import 'module.ec2.aws_instance.pds_ec2["<instance_name>"]' <instance-id>

    (#59)

  • EC2 module requires an explicit ami_id and instance profile. Affects ec2 callers.
    There is no default AMI and no name-based auto-detection, and the default instance profile is gone. Pass the AMI ID for your venue and an instance profile created by iam/roles/ec2.
    (6a9d422)

  • IAM module restructured under iam/roles. Affects iam callers.
    The top-level iam module and its dev_roles.yml/prod_roles.yml files are removed. Use iam/roles and update the module call to the new variable interface.
    (c861005)

  • s3/bucket rejects versioning = "Suspended" and adds a default cleanup rule. Affects s3/bucket callers.
    Only Enabled or Disabled are accepted. Buckets with versioning = "Enabled" get a lifecycle rule on the next apply that expires noncurrent versions older than 90 days, keeping the 2 newest. Set noncurrent_version_expiration_days = 0 to keep the old behavior.
    (#56)

  • Default S3 bucket policy no longer allows s3:* for the platform-engineer role. Only the SSL-requests-only deny statement remains. Add an explicit statement if you relied on it.
    (6a9d422)

Highlights

  • Pin infrastructure to a stable, tagged version of the PDC modules (#62)
  • New reusable bastion host module for SSH access to private instances (#52)
  • EC2 edits (user data, security groups, tags, instance type) now show up in plans and reach running instances (#59)
  • S3 buckets can opt in to Object Lock and version/log retention for long-lived data (#56)
  • IAM role module for EC2 instances, with role and profile published to SSM (6a9d422)

New

  • Bastion module (bastion): scoped SSH security groups, optional Elastic IP, and no IAM or key pairs in the module. Defaults to t3.medium; nano, micro and small sizes are rejected (#52, #57)
  • iam/roles/ec2 module: creates the EC2 instance role and profile with CloudWatch agent, SSM and ec2users DynamoDB policies, and publishes both to SSM under /pds/<component>/iam/roles/ec2/ (6a9d422)
  • S3 Object Lock (opt-in, Governance mode): object_lock_enabled, object_lock_days (#56)
  • S3 retention controls: noncurrent-version cleanup and opt-in object_expiration_days for log buckets (#56)
  • S3 storage-class lifecycle transitions (Intelligent-Tiering, Glacier, etc.) on s3/bucket (4eb8cb7)
  • S3 server access logging on s3/bucket (d7d57a2)
  • EC2 per-instance flags: ignore_instance_profile_changes and user_data_replace_on_change; instances are tagged Patch = true for patching automation (#59)
  • CloudFront rewrite for the Nucleus Airflow UI, giving it a friendly URL (bf64649)
  • Cognito: user pool redirect to a welcome page and UI customizations (#10)
  • CloudFront: registry-api, s3-browser and default S3 website distributions; portal-wp origin (#9, #13)
  • ECS, OpenSearch Serverless, S3 bucket/object and IAM modules (d0b08a2, c0fc717, #15)

Improvements

  • Default EC2 root volume size increases from 30 GB to 50 GB (6a9d422)
  • EC2 and iam/roles/ec2 modules are documented and marked as actively used (6a9d422)
  • Every module has a README, and the root README lists each module's status (d1ea5f6)
  • required_tags are applied on s3/bucket, and EC2 and S3 modules meet SCP tagging requirements (4eb8cb7, c861005)
  • ec2users-dynamodb inline policy adds dynamodb:Scan (781044e)
  • Cognito module warns that user-pool client changes can break the login URL (43e0a5b)
  • Secrets scanning uses a script-based detect-secrets baseline with pre-commit and CI checks (6a9d422)

Fixes

  • Fixes RunInstances MissingParameter error from a missing root volume size; adds root_volume_size and root_volume_type (6a9d422)
  • Prevents Terraform plan failure when S3 source files are built during apply (4c66198)
  • Fixes missing brace in the CloudFront Terraform (d66d7fa)
  • Fixes CloudFront trailing-slash handling (#14)
  • Root volumes are deleted with the instance, so replace/destroy no longer orphans EBS volumes (#52)
  • Fixes concurrent issue-automation runs overwriting each other's field values (a8d4fe5, #55)

Security

  • EC2 instances require IMDSv2 (#52)
  • EC2 instances are private by default (associate_public_ip_address = false) (c861005)
  • Narrows the default S3 bucket policy; the SSL-only deny remains (6a9d422)
  • CI pip install steps pin exact versions and use --only-binary :all: (6a9d422)

Compatibility

  • Requires Terraform 1.2 or later when using s3/bucket (it uses a precondition). The root provider.tf still allows >= 1.0.11 (#56).

Known issues

  • bastion instance-type validation matches size names, not memory, so it would accept a 2 GiB size from another family such as c6g.medium (#57)
  • S3 Object Lock cannot be turned off once enabled; changing true to false forces bucket replacement (#56)
  • Adopting an existing EC2 instance via terraform import is untested (#59)

Links