diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 26f2653..ce4c463 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,6 +8,9 @@ on: env: AWS_REGION: eu-west-3 + ORIGIN_BUCKET_NAME: twitch-live-17102024-my-web-site-origin + ROLE_ARN: arn:aws:iam::448878779811:role/twitch-live-17102024-my-web-site + ROLE_SESSON_NAME: github-ipppontech-my-web-site-to-aws-via-oidc # Permission can be added at job level or workflow level permissions: @@ -24,8 +27,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::448878779811:role/twitch-live-1710204-my-web-site - role-session-name: github-ipppontech-my-web-site-to-aws-via-oidc + role-to-assume: ${{ env.ROLE_ARN }} + role-session-name: ${{ env.ROLE_SESSION_NAME }} aws-region: ${{ env.AWS_REGION }} - uses: hashicorp/setup-terraform@v3 with: @@ -47,8 +50,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::448878779811:role/twitch-live-1710204-my-web-site - role-session-name: github-ipppontech-my-web-site-to-aws-via-oidc + role-to-assume: ${{ env.ROLE_ARN }} + role-session-name: ${{ env.ROLE_SESSION_NAME }} aws-region: ${{ env.AWS_REGION }} - uses: hashicorp/setup-terraform@v3 with: @@ -70,8 +73,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - role-to-assume: arn:aws:iam::448878779811:role/twitch-live-1710204-my-web-site - role-session-name: github-ipppontech-my-web-site-to-aws-via-oidc + role-to-assume: ${{ env.ROLE_ARN }} + role-session-name: ${{ env.ROLE_SESSION_NAME }} aws-region: ${{ env.AWS_REGION }} - name: Use Node.js LTS uses: actions/setup-node@v4 @@ -87,6 +90,18 @@ jobs: run: | npm ci npm run build + - name: clean S3 origin bucket + run: | + objects_number=$(aws s3 ls s3://twitch-live-17102024-my-web-site-origin/ --recursive | wc -l) + if [ "$objects_number" -gt "0" ]; then + aws s3api delete-objects \ + --bucket ${{ env.ORIGIN_BUCKET_NAME }} \ + --delete "$(aws s3api list-object-versions \ + --bucket ${{ env.ORIGIN_BUCKET_NAME }} \ + --output=json \ + --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"; + fi + - name: copy dist folder to S3 run: | - aws s3 cp --recursive dist s3://twitch-live-17102024-my-web-site-origin/ + aws s3 cp --recursive dist s3://${{ env.ORIGIN_BUCKET_NAME }}/ diff --git a/.gitignore b/.gitignore index 7dedfb5..dc6df0b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,27 @@ !.vscode/launch.json !.vscode/extensions.json *.code-workspace + +###################### +# Terraform +###################### +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# tf plan files +**.tfplan +**.plan.json + +# Ignore CLI configuration files +.terraformrc +terraform.rc +~ +# ignore temp doc file +doc.md + +# ignore zip files generated with data_archive +*.zip diff --git a/infrastructure/10_bootstrap/.terraform.lock.hcl b/infrastructure/10_bootstrap/.terraform.lock.hcl new file mode 100644 index 0000000..d38cb8a --- /dev/null +++ b/infrastructure/10_bootstrap/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.72.1" + constraints = "~> 5.0" + hashes = [ + "h1:BkYfMmqLJIqLkLLz9sDRWJR5+7GCXTocNPN4pIHkhQo=", + "zh:0dea6843836e926d33469b48b948744079023816d16a2ff7666bcfb6aa3522d4", + "zh:195fa9513f75800a0d62797ebec75ee73e9b8c28d713fe9b63d3b1d1eec129b3", + "zh:1ed92f3961715bf0e024bcde3c12dfbdc50b00c1f8a43cc00802cfc45a256208", + "zh:2ac687e3a52606466cae4a6813e81d923042488df88d2424e28d3f8530f091bb", + "zh:32e7ca75f9314557daada3c44628fe1f3bf964a4f833bfb4b2295d833fe64b6f", + "zh:374ee0e6b4327cc6ef666908ce5d6450a3a56e90cd2b785e83c2bcfc100021d2", + "zh:5500fd6fdac44f96411fcf9c6d01691159ec35455ed127eb4c3a498e1cc92a64", + "zh:723a2dc4b064c12e7ee62ad4fbfd72fa5e025206ea47b735994ef53f3c373152", + "zh:89d97b87605f1d734f27e642567cbecf785b521af8ea81dac55c77ccde876221", + "zh:951ee1e5731e8d65d521d71b95927e55055b3c4656eef6d46fa580a63328befc", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9b2b362470b64ec227b2da64762ab8bc4111c6b80365fd9d82fc5e1e33f44038", + "zh:aa6e57d0cb974ff0da5dee5d43ad2745cbbc4a2b507d4c799839b9fa96daf688", + "zh:ba0d14c4a6b7aa844a830d47c0bf995b632e37f0795394b5b60c638b62b7fc03", + "zh:c9764065a9c5d324db0b02bd201b9e3a2118e49c4960884acdeea377173302e9", + ] +} diff --git a/infrastructure/10_bootstrap/github_oidc.tf b/infrastructure/10_bootstrap/github_oidc.tf index 36a2701..85fd88f 100644 --- a/infrastructure/10_bootstrap/github_oidc.tf +++ b/infrastructure/10_bootstrap/github_oidc.tf @@ -1,10 +1,5 @@ locals { - role_name = "twitch-live-1710204-my-web-site" -} - -import { - to = aws_iam_openid_connect_provider.github - id = "arn:aws:iam::448878779811:oidc-provider/token.actions.githubusercontent.com" + role_name = "twitch-live-17102024-my-web-site" } resource "aws_iam_openid_connect_provider" "github" { @@ -17,11 +12,6 @@ resource "aws_iam_openid_connect_provider" "github" { thumbprint_list = ["d89e3bd43d5d909b47a18977aa9d5ce36cee184c"] } -import { - to = aws_iam_role.twitch_live - id = local.role_name -} - resource "aws_iam_role" "twitch_live" { name = local.role_name description = "Role dedicated to deploy infrastructure during the Twitch Live on October 17th 2024 with Arnaud and Timothee" @@ -102,7 +92,7 @@ data "aws_iam_policy_document" "twitch_live_runner" { "iam:*" ] resources = [ - "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/twitch-live-1710204-my-web-site" + "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/twitch-live-17102024-my-web-site" ] } } diff --git a/infrastructure/20_cloudfront/.terraform.lock.hcl b/infrastructure/20_cloudfront/.terraform.lock.hcl new file mode 100644 index 0000000..f0b42db --- /dev/null +++ b/infrastructure/20_cloudfront/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.72.1" + constraints = "~> 5.0, >= 5.70.0" + hashes = [ + "h1:BkYfMmqLJIqLkLLz9sDRWJR5+7GCXTocNPN4pIHkhQo=", + "zh:0dea6843836e926d33469b48b948744079023816d16a2ff7666bcfb6aa3522d4", + "zh:195fa9513f75800a0d62797ebec75ee73e9b8c28d713fe9b63d3b1d1eec129b3", + "zh:1ed92f3961715bf0e024bcde3c12dfbdc50b00c1f8a43cc00802cfc45a256208", + "zh:2ac687e3a52606466cae4a6813e81d923042488df88d2424e28d3f8530f091bb", + "zh:32e7ca75f9314557daada3c44628fe1f3bf964a4f833bfb4b2295d833fe64b6f", + "zh:374ee0e6b4327cc6ef666908ce5d6450a3a56e90cd2b785e83c2bcfc100021d2", + "zh:5500fd6fdac44f96411fcf9c6d01691159ec35455ed127eb4c3a498e1cc92a64", + "zh:723a2dc4b064c12e7ee62ad4fbfd72fa5e025206ea47b735994ef53f3c373152", + "zh:89d97b87605f1d734f27e642567cbecf785b521af8ea81dac55c77ccde876221", + "zh:951ee1e5731e8d65d521d71b95927e55055b3c4656eef6d46fa580a63328befc", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9b2b362470b64ec227b2da64762ab8bc4111c6b80365fd9d82fc5e1e33f44038", + "zh:aa6e57d0cb974ff0da5dee5d43ad2745cbbc4a2b507d4c799839b9fa96daf688", + "zh:ba0d14c4a6b7aa844a830d47c0bf995b632e37f0795394b5b60c638b62b7fc03", + "zh:c9764065a9c5d324db0b02bd201b9e3a2118e49c4960884acdeea377173302e9", + ] +} diff --git a/infrastructure/20_cloudfront/cloudfront.tf b/infrastructure/20_cloudfront/cloudfront.tf index 766db04..8fa1c33 100644 --- a/infrastructure/20_cloudfront/cloudfront.tf +++ b/infrastructure/20_cloudfront/cloudfront.tf @@ -3,7 +3,8 @@ locals { } module "cdn" { - source = "terraform-aws-modules/cloudfront/aws" + source = "terraform-aws-modules/cloudfront/aws" + version = "3.4.1" # aliases = ["cdn.example.com"] @@ -12,7 +13,7 @@ module "cdn" { is_ipv6_enabled = true price_class = "PriceClass_All" retain_on_delete = false - wait_for_deployment = false + wait_for_deployment = true create_origin_access_identity = true @@ -37,6 +38,7 @@ module "cdn" { target_origin_id = local.origin_id viewer_protocol_policy = "allow-all" } + # viewer_certificate = { # acm_certificate_arn = "arn:aws:acm:us-east-1:135367859851:certificate/1032b155-22da-4ae0-9f69-e206f825458b" # ssl_support_method = "sni-only" diff --git a/infrastructure/20_cloudfront/s3_origin.tf b/infrastructure/20_cloudfront/s3_origin.tf index b5d0b84..6d5500b 100644 --- a/infrastructure/20_cloudfront/s3_origin.tf +++ b/infrastructure/20_cloudfront/s3_origin.tf @@ -3,13 +3,13 @@ locals { } module "s3_bucket" { - source = "terraform-aws-modules/s3-bucket/aws" + source = "terraform-aws-modules/s3-bucket/aws" + version = "4.2.1" bucket = local.origin_bucket_name - acl = "private" control_object_ownership = true - object_ownership = "ObjectWriter" + object_ownership = "BucketOwnerEnforced" server_side_encryption_configuration = { rule = { @@ -19,15 +19,36 @@ module "s3_bucket" { } } - # policy = data.aws_iam_policy_document.origin_bucket_policy.json + attach_policy = true + policy = data.aws_iam_policy_document.origin_bucket_policy.json + + # For tests only + force_destroy = true } -# data "aws_iam_policy_document" "origin_bucket_policy" { -# statement { -# effect = "Allow" -# principals { -# -# } -# } -# } +data "aws_iam_policy_document" "origin_bucket_policy" { + # Origin Access Controls + statement { + sid = "S3GetObjectsDistribution" + actions = [ + "s3:GetObject" + ] + resources = [ + "${module.s3_bucket.s3_bucket_arn}/*" + ] + + principals { + type = "Service" + identifiers = ["cloudfront.amazonaws.com"] + } + + condition { + test = "StringEquals" + variable = "aws:SourceArn" + values = [ + module.cdn.cloudfront_distribution_arn + ] + } + } +}