diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f3031f..6de42b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + - name: Bump Version id: tag_version uses: mathieudutour/github-tag-action@v6.1 @@ -21,6 +22,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} default_bump: minor custom_release_rules: bug:patch:Fixes,chore:patch:Chores,docs:patch:Documentation,feat:minor:Features,refactor:minor:Refactors,test:patch:Tests,ci:patch:Development,dev:patch:Development + - name: Create Release uses: ncipollo/release-action@v1.12.0 with: diff --git a/.github/workflows/semantic-check.yml b/.github/workflows/semantic-check.yml index 2e5d44f..684f992 100644 --- a/.github/workflows/semantic-check.yml +++ b/.github/workflows/semantic-check.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: amannn/action-semantic-pull-request@v5.2.0 name: Check PR for Semantic Commit Message env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 679d22b..08c87e5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,20 +2,70 @@ name: test on: pull_request: - branches: - - main + branches: [ main ] + push: + branches: [ main ] + +permissions: + contents: read + pull-requests: write + +env: + TF_IN_AUTOMATION: true jobs: - test: + lint: + name: lint runs-on: ubuntu-latest + steps: - - name: Checkout Code - uses: actions/checkout@v3 - - name: Terraform Setup - run: | - terraform init + - name: Checkout + uses: actions/checkout@v4 + + - name: setup terraform + uses: hashicorp/setup-terraform@v3 + + - name: Cache Terraform Plugins + uses: actions/cache@v4 + with: + path: ${{ runner.temp }}/.terraform.d/plugin-cache + key: tf-plugins-${{ runner.os }}-${{ hashFiles('**/.terraform.lock.hcl') }} + + - name: Initialize Terraform + run: terraform init + + - name: Suggest Terraform Format + if: github.event_name == 'pull_request' + uses: reviewdog/action-suggester@v1 + with: + tool_name: terraform-fmt + level: warning + github_token: ${{ secrets.GITHUB_TOKEN }} + fail_level: error + + - name: Check Terraform Format + if: github.event_name == 'push' + run: terraform fmt -recursive -check + + - name: Validate Terraform + uses: reviewdog/action-terraform-validate@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + reporter: github-pr-review + level: warning + fail_level: error + - name: Lint Terraform - uses: reviewdog/action-tflint@master + uses: reviewdog/action-tflint@v1 + with: + reporter: github-pr-review + filter_mode: nofilter + fail_level: error + + - name: Lint GitHub Actions + uses: reviewdog/action-actionlint@v1 with: - github_token: ${{ secrets.github_token }} - filter_mode: "nofilter" + reporter: github-pr-check + fail_level: error + filter_mode: nofilter + diff --git a/main.tf b/main.tf index 90a037f..3886e52 100644 --- a/main.tf +++ b/main.tf @@ -1,4 +1,6 @@ locals { + aws_partition = data.aws_partition.current.partition + vpc_dns_resolver = module.this.enabled ? cidrhost(data.aws_vpc.lookup[0].cidr_block, 2) : "10.0.0.2" proxies = { for k, v in var.proxies : k => merge(v, { name = k }) } proxies_port_range = [local.proxies.default.listener_port, local.proxies.default.listener_port] @@ -27,16 +29,18 @@ locals { } } +data "aws_partition" "current" {} + # ================================================================== service === module "proxy" { source = "cloudposse/ec2-autoscale-group/aws" - version = "0.41.0" + version = "0.41.1" image_id = data.aws_ssm_parameter.linux_ami.value instance_type = "t3.nano" health_check_type = "ELB" - user_data_base64 = base64encode(module.this.enabled ? data.template_cloudinit_config.this[0].rendered : "") + user_data_base64 = base64encode(module.this.enabled ? data.cloudinit_config.this[0].rendered : "") force_delete = true disable_api_termination = false update_default_version = true @@ -50,39 +54,27 @@ module "proxy" { } iam_instance_profile_name = module.this.enabled ? resource.aws_iam_instance_profile.this[0].id : null - key_name = "" + key_name = var.key_name metadata_http_tokens_required = true autoscaling_policies_enabled = false desired_capacity = local.capacity.desired - min_size = var.capacity.min - max_size = var.capacity.max + min_size = local.capacity.min + max_size = local.capacity.max max_instance_lifetime = "604800" wait_for_capacity_timeout = "300s" tag_specifications_resource_types = ["instance", "volume", "spot-instances-request"] mixed_instances_policy = { instances_distribution = { - on_demand_base_capacity = 0 - on_demand_percentage_above_base_capacity = 0 + on_demand_base_capacity = var.spot.enabled ? 0 : 100 + on_demand_percentage_above_base_capacity = var.spot.enabled ? 0 : 100 on_demand_allocation_strategy = "prioritized" - spot_allocation_strategy = "capacity-optimized" + spot_allocation_strategy = var.spot.allocation_strategy spot_instance_pools = 0 spot_max_price = "" } - override = [{ - instance_type = "t3.nano" - weighted_capacity = 1 - }, { - instance_type = "t3a.nano" - weighted_capacity = 1 - }, { - instance_type = "t3.micro" - weighted_capacity = 1 - }, { - instance_type = "t3a.micro" - weighted_capacity = 1 - }] + override = [for x in var.instance_types : { instance_type = x.type, weighted_capacity = x.weight }] } associate_public_ip_address = false @@ -94,7 +86,7 @@ module "proxy" { context = module.this.context } -data "template_cloudinit_config" "this" { +data "cloudinit_config" "this" { count = module.this.enabled ? 1 : 0 gzip = true @@ -266,7 +258,7 @@ resource "aws_iam_role_policy_attachment" "ssm_managed_instance_core" { count = module.this.enabled ? 1 : 0 role = resource.aws_iam_role.this[0].name - policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + policy_arn = "arn:${local.aws_partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" } resource "aws_iam_policy" "this" { @@ -307,8 +299,8 @@ data "aws_iam_policy_document" "this" { "s3:GetBucketLocation", ] resources = [ - "arn:aws:s3:::${var.ssm_sessions.logs_bucket_name}", - "arn:aws:s3:::${var.ssm_sessions.logs_bucket_name}/*" + "arn:${local.aws_partition}:s3:::${var.ssm_sessions.logs_bucket_name}", + "arn:${local.aws_partition}:s3:::${var.ssm_sessions.logs_bucket_name}/*" ] } } diff --git a/variables.tf b/variables.tf index 7d9bbe9..aee9387 100644 --- a/variables.tf +++ b/variables.tf @@ -27,6 +27,24 @@ variable "capacity" { default = {} } +variable "instance_types" { + type = list(object({ + type = string + weight = optional(number, 1) + })) + description = "List of instance types and their weighted capacity to be used." + default = [{ type = "t3.nano" }, { type = "t3a.nano" }, { type = "t3.micro" }, { type = "t3a.micro" }] +} + +variable "spot" { + type = object({ + enabled = optional(bool, true) + allocation_strategy = optional(string, "capacity-optimized") + }) + description = "Configuration of spot instances" + default = {} +} + variable "logs_bucket_name" { type = string description = "S3 bucket for storing logs." @@ -44,6 +62,12 @@ variable "ssm_sessions" { # --------------------------------------------------------------- networking --- +variable "key_name" { + type = string + description = "Name of existing SSH key to be assigned to instances." + default = "" +} + variable "public_accessible" { type = bool description = "Toggle whether the NLB is publicly accessible."