{"id":34728540,"url":"https://github.com/labzero/gitops_terraform_demo","last_synced_at":"2026-03-13T16:32:08.578Z","repository":{"id":221229253,"uuid":"753794779","full_name":"labzero/gitops_terraform_demo","owner":"labzero","description":"GitOps demo using GitHub Actions and Terraform to provision S3 bucket","archived":false,"fork":false,"pushed_at":"2024-03-28T18:26:00.000Z","size":28,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-03-28T19:48:30.113Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/labzero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-02-06T20:03:16.000Z","updated_at":"2024-02-13T18:31:34.000Z","dependencies_parsed_at":"2024-03-28T19:46:29.526Z","dependency_job_id":"5b0062f4-9ca1-47e6-92db-8ad0b0e55db3","html_url":"https://github.com/labzero/gitops_terraform_demo","commit_stats":null,"previous_names":["labzero/gitops_terraform_demo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/labzero/gitops_terraform_demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labzero%2Fgitops_terraform_demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labzero%2Fgitops_terraform_demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labzero%2Fgitops_terraform_demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labzero%2Fgitops_terraform_demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/labzero","download_url":"https://codeload.github.com/labzero/gitops_terraform_demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labzero%2Fgitops_terraform_demo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30471035,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T11:00:43.441Z","status":"ssl_error","status_checked_at":"2026-03-13T11:00:23.173Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-25T02:54:32.446Z","updated_at":"2026-03-13T16:32:08.569Z","avatar_url":"https://github.com/labzero.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gitops_terraform_demo\nGitOps demo using GitHub Actions and Terraform to provision S3 bucket\n\n\n### AWS Provider\n\n- AWS provider with version pinning\n- Backend S3 bucket for state file\n- DyanmoDB table for state file locking\n- Default tags for provisioned resources\n\n```hcl\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"4.45.0\"\n    }\n  }\n\n  required_version = \"\u003e= 1.3.6\"\n\n  # tfstate stored on S3 \n  backend \"s3\" {\n    bucket         = \"labzero-terraform-state\"\n    key            = \"iac-s3-demo/terraform.tfstate\"\n    region         = \"us-west-2\"\n    dynamodb_table = \"terraform-state-lock-table\"\n  }\n}\n\nprovider \"aws\" {\n  default_tags {\n    tags = {\n      Product = \"lz-iac-s3-demo\"\n    }\n  }\n}\n```\n\n### Initial S3 bucket provisioning.\n\n- Simple provisioned S3 bucket.\n\n```hcl\nresource \"aws_s3_bucket\" \"s3_iac_example\" {\n  bucket = \"lz-s3-iac-example\"\n}\n```\n\n### Run Terraform Plan\n\n- Terraform plan to generate speculative plan pre-deploy\n\n~~~text\nTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:\n  + create\n\nTerraform will perform the following actions:\n\n  # aws_s3_bucket.s3_iac_example will be created\n  + resource \"aws_s3_bucket\" \"s3_iac_example\" {\n      + acceleration_status         = (known after apply)\n      + acl                         = (known after apply)\n      + arn                         = (known after apply)\n      + bucket                      = \"lz-s3-iac-example\"\n      + bucket_domain_name          = (known after apply)\n      + bucket_regional_domain_name = (known after apply)\n      + force_destroy               = false\n      + hosted_zone_id              = (known after apply)\n      + id                          = (known after apply)\n      + object_lock_enabled         = (known after apply)\n      + policy                      = (known after apply)\n      + region                      = (known after apply)\n      + request_payer               = (known after apply)\n      + tags_all                    = {\n          + \"Product\" = \"lz-iac-s3-demo\"\n        }\n      + website_domain              = (known after apply)\n      + website_endpoint            = (known after apply)\n    }\n\nPlan: 1 to add, 0 to change, 0 to destroy.\n~~~\n\n### Checkov scanning\n\n- Run [checkov](https://github.com/bridgecrewio/checkov) static analysis for common misconfigurations\n\n  Potential Misconfiguration Errors\n\n  1. CKV2_AWS_6: (Low) Ensure that S3 bucket has a Public Access block\n  2. CKV_AWS_18: (Low) Ensure the S3 bucket has access logging enabled \n  3. CKV_AWS_21: (High) Ensure all data stored in the S3 bucket have versioning enabled\n  4. CKV2_AWS_61: (Medium) Ensure that an S3 bucket has a lifecycle configuration\n  5. CKV2_AWS_62: (Low) Ensure S3 buckets should have event notifications enabled\n  6. CKV_AWS_144: (Low) Ensure that S3 bucket has cross-region replication enabled\n  7. CKV_AWS_145: (Low) Ensure that S3 buckets are encrypted with KMS by default\n\n\n  Let's address issues 1-4.  We will suppress issues 5-7 for the purpose of this demo in the [.checkov.yaml](./.checkov.yaml) file.  You should address these issues depending on your security needs for your S3 resource.\n\n~~~text\nterraform scan results:\n\nPassed checks: 5, Failed checks: 7, Skipped checks: 0\n\nCheck: CKV_AWS_93: \"Ensure S3 bucket policy does not lockout all but root user. (Prevent lockouts needing root account fixes)\"\n\tPASSED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/bc-aws-s3-24\nCheck: CKV_AWS_41: \"Ensure no hard coded AWS access key and secret key exists in provider\"\n\tPASSED for resource: aws.default\n\tFile: /main.tf:20-26\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/secrets-policies/bc-aws-secrets-5\nCheck: CKV_AWS_20: \"S3 Bucket has an ACL defined which allows public READ access.\"\n\tPASSED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/s3-1-acl-read-permissions-everyone\nCheck: CKV_AWS_57: \"S3 Bucket has an ACL defined which allows public WRITE access.\"\n\tPASSED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/s3-2-acl-write-permissions-everyone\nCheck: CKV_AWS_19: \"Ensure all data stored in the S3 bucket is securely encrypted at rest\"\n\tPASSED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/s3-14-data-encrypted-at-rest\nCheck: CKV_AWS_18: \"Ensure the S3 bucket has access logging enabled\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/s3-13-enable-logging\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n\nCheck: CKV2_AWS_61: \"Ensure that an S3 bucket has a lifecycle configuration\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-logging-policies/bc-aws-2-61\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n\nCheck: CKV2_AWS_62: \"Ensure S3 buckets should have event notifications enabled\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-logging-policies/bc-aws-2-62\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n\nCheck: CKV2_AWS_6: \"Ensure that S3 bucket has a Public Access block\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/s3-bucket-should-have-public-access-blocks-defaults-to-false-if-the-public-access-block-is-not-attached\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n\nCheck: CKV_AWS_145: \"Ensure that S3 buckets are encrypted with KMS by default\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-general-policies/ensure-that-s3-buckets-are-encrypted-with-kms-by-default\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n\nCheck: CKV_AWS_144: \"Ensure that S3 bucket has cross-region replication enabled\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-general-policies/ensure-that-s3-bucket-has-cross-region-replication-enabled\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n\nCheck: CKV_AWS_21: \"Ensure all data stored in the S3 bucket have versioning enabled\"\n\tFAILED for resource: aws_s3_bucket.s3_iac_example\n\tFile: /main.tf:28-30\n\tGuide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/s3-policies/s3-16-enable-versioning\n\n\t\t28 | resource \"aws_s3_bucket\" \"s3_iac_example\" {\n\t\t29 |   bucket = \"lz-s3-iac-example\"\n\t\t30 | }\n~~~\n\n### Fixing Misconfigurations\n\n  The following changes address the four S3 misconfigurations.\n\n- CKV2_AWS_6: `aws_s3_bucket_public_access_block`\n- CKV_AWS_18: `aws_s3_bucket_logging`\n- CKV_AWS_21: `aws_s3_bucket_versioning`\n- CKV2_AWS_61: `aws_s3_bucket_lifecycle_configuration`\n\n\n```hcl\nresource \"aws_s3_bucket\" \"s3_iac_example\" {\n  bucket = \"lz-s3-iac-example\"\n}\n\nresource \"aws_s3_bucket_lifecycle_configuration\" \"s3_iac_example\" {\n  bucket = aws_s3_bucket.s3_iac_example.id\n  rule {\n    id     = \"expire\"\n    status = \"Enabled\"\n    transition {\n      days          = 30\n      storage_class = \"STANDARD_IA\"\n    }\n    expiration {\n      days = 90\n    }\n\n    abort_incomplete_multipart_upload {\n      days_after_initiation = 7\n    }\n  }\n}\n\nresource \"aws_s3_bucket_versioning\" \"s3_iac_example_versioning\" {\n  bucket = aws_s3_bucket.s3_iac_example.id\n  versioning_configuration {\n    status = \"Enabled\"\n  }\n}\n\nresource \"aws_s3_bucket_public_access_block\" \"access_s3_iac_example\" {\n  bucket = aws_s3_bucket.s3_iac_example.id\n\n  block_public_acls       = true\n  block_public_policy     = true\n  restrict_public_buckets = true\n  ignore_public_acls      = true\n}\n\nresource \"aws_s3_bucket\" \"log_bucket\" {\n  bucket = \"lz-s3-iac-example-log-bucket\"\n}\n\nresource \"aws_s3_bucket_lifecycle_configuration\" \"s3_iac_example\" {\n  bucket = aws_s3_bucket.log_bucket.id\n  rule {\n    id     = \"expire\"\n    status = \"Enabled\"\n    transition {\n      days          = 30\n      storage_class = \"STANDARD_IA\"\n    }\n    expiration {\n      days = 90\n    }\n\n    abort_incomplete_multipart_upload {\n      days_after_initiation = 7\n    }\n  }\n}\n\nresource \"aws_s3_bucket_versioning\" \"log_bucket_versioning\" {\n  bucket = aws_s3_bucket.log_bucket.id\n  versioning_configuration {\n    status = \"Enabled\"\n  }\n}\n\nresource \"aws_s3_bucket_public_access_block\" \"access_log_bucket\" {\n  bucket = aws_s3_bucket.log_bucket.id\n\n  block_public_acls       = true\n  block_public_policy     = true\n  restrict_public_buckets = true\n  ignore_public_acls      = true\n}\n\n\nresource \"aws_s3_bucket_acl\" \"log_bucket_acl\" {\n  bucket = aws_s3_bucket.log_bucket.id\n  acl    = \"log-delivery-write\"\n}\n\nresource \"aws_s3_bucket_logging\" \"s3_iac_bucket_logging\" {\n  bucket        = aws_s3_bucket.s3_iac_example.id\n  target_bucket = aws_s3_bucket.log_bucket.id\n  target_prefix = \"log/\"\n}\n\n```\n\n### GitHub Action \n\nUsing GitHub Action as part of a GitOps flow for validating the terraform configuration files during a Pull Request.\n\nFor the PR we will run the two jobs,  `static-analysis-scanning` and then `terraform-plan`.\n\n```yaml\nname: pr-builder\nrun-name: PR Builder\non: pull_request\n\npermissions: read-all\njobs:      \n  static-analysis-scanning:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@master\n    - name: Checkov Scan\n      uses: bridgecrewio/checkov-action@v12\n      with:\n        output_format: cli\n        output_file_path: console      \n  terraform-plan:\n    needs: static-analysis-scanning\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@master    \n\n    # Configure AWS Credentials to deploy terraform changes onto AWS\n    - name: Configure AWS Credentials\n      uses: aws-actions/configure-aws-credentials@v4\n      with:\n        aws-region: us-west-2\n        # This is an assumed role created for GitHub Actions to access the statefile of this terraform project\n        role-to-assume: arn:aws:iam::295919900413:role/iac-s3-example-role\n        role-session-name: S3IaCExampleRole\n\n    # Terraform Cloud Authentication\n    - uses: hashicorp/setup-terraform@v3\n      with:\n        terraform_version: 1.7.2\n        terraform_wrapper: false\n    \n    - name: Terraform Format\n      run: terraform fmt -check\n    \n    - name: Terraform Init\n      run: terraform init\n    \n    - name: Terraform Plan\n      run: terraform plan -out=tfplan\n      continue-on-error: true\n    \n    - name: Upload TF Plan  \n      uses: actions/upload-artifact@v4\n      with:\n        name: tfplan\n        path: tfplan\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flabzero%2Fgitops_terraform_demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flabzero%2Fgitops_terraform_demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flabzero%2Fgitops_terraform_demo/lists"}