From f78af20a20cfb65b7d39a86e9ac3e6021240fbe8 Mon Sep 17 00:00:00 2001 From: Andrew Kay Date: Thu, 7 Oct 2021 22:38:59 -0500 Subject: [PATCH] Add CI infrastructure --- .ci/infrastructure/.gitignore | 34 ++++++++ .ci/infrastructure/.terraform.lock.hcl | 42 +++++++++ .ci/infrastructure/main.tf | 115 +++++++++++++++++++++++++ .ci/infrastructure/outputs.tf | 4 + .ci/infrastructure/providers.tf | 5 ++ .ci/infrastructure/versions.tf | 13 +++ 6 files changed, 213 insertions(+) create mode 100644 .ci/infrastructure/.gitignore create mode 100644 .ci/infrastructure/.terraform.lock.hcl create mode 100644 .ci/infrastructure/main.tf create mode 100644 .ci/infrastructure/outputs.tf create mode 100644 .ci/infrastructure/providers.tf create mode 100644 .ci/infrastructure/versions.tf diff --git a/.ci/infrastructure/.gitignore b/.ci/infrastructure/.gitignore new file mode 100644 index 0000000..18221f8 --- /dev/null +++ b/.ci/infrastructure/.gitignore @@ -0,0 +1,34 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Exclude all .tfvars files, which are likely to contain sentitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +# +*.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc diff --git a/.ci/infrastructure/.terraform.lock.hcl b/.ci/infrastructure/.terraform.lock.hcl new file mode 100644 index 0000000..cf7b21c --- /dev/null +++ b/.ci/infrastructure/.terraform.lock.hcl @@ -0,0 +1,42 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "3.62.0" + constraints = "~> 3.0" + hashes = [ + "h1:OxJqmYKlCkE5iJK3/NoCP+9EQXQQD2ORdwnRIHaTlgs=", + "zh:08a94019e17304f5927d7c85b8f5dade6b9ffebeb7b06ec0643aaa1130c4c85d", + "zh:0e3709f6c1fed8c5119a5653bec7e3069258ddf91f62d851f8deeede10487fb8", + "zh:0ed32886abce5fee49f1ae49b84472558224366c31a638e51c63061c3126e7c2", + "zh:0f1ecbeddfa61d87701a3f3b463e508773171981bf6dad8b1313a9eafaffd5e1", + "zh:724cde4f27253b547714a606288ede17f5df67f430438478feed113d7acb5ac7", + "zh:81e6e751a168eab1a054230d4441b43c68693bfb6e0545536f2ea6dbb39fe9af", + "zh:84deaf1c6661ba0dbc07ac159109fb6746772476646d39854c755c8dfb7a8ac4", + "zh:909dcefc6c986c926ad856662ab5d38a3988b1906569387b5b58e7ddd89a155c", + "zh:d03886705e9f25d4bebeae115bb07e36adb14e778859cedb2bf3c3bed39f4d2b", + "zh:de9fc80c5a5d3be7535856242c823a92516eb7d5c16ae509fa10b92cd6b3fa9b", + "zh:e91dcd9eec8b779a9b089f2f8d45f1047f890cb7b9241490451da52c04cef63d", + ] +} + +provider "registry.terraform.io/integrations/github" { + version = "4.16.0" + constraints = "~> 4.0" + hashes = [ + "h1:IrC2CowOQFtQCwDsysvS1fb46197Z5i0wIKslB1GnF8=", + "zh:24454b9082c5793d288e560d631c49ca4a803c26f151cb2853adb8966403f672", + "zh:2fbac366eaa67ef6ba0ad3714cbf0a795303bc8f1131bafec3bfa02fc87c90fb", + "zh:2fdf6daa059d4e996ed908d4a35dd65f681914f521ba7e47e57f292e4de525d2", + "zh:31704c3b3963a6ef18e38812cec6993e3f81c31e8a76ee047b2fc0e5cbb176d3", + "zh:84ef0f7002717d63b10457b83df7c649a4e347f2ebcd69c1912190938a1fb6c5", + "zh:8ed0af87ce15eece9414870134a8b68dfef064da8d584167366bdda824159f45", + "zh:995c61d6d6e3b1d2c020a6666fe9ab73b6eebddfb1c6209c9711bf26d62781fd", + "zh:9c2bed37302f4414eefc6751c0e2cba702d76286caaa4ea931d218c544e52e63", + "zh:b2b28adbff9cc2fcfa221de4cdf8b2b17bd4fdd7c6ba5aa73153387e02d4e7f5", + "zh:b7143da120c9799233f667e738dc94e49e9a325689aa4ca629766ec6577300a6", + "zh:f671bb37978affb5ff876c9fb1815fdcad52549f607276db7c0c70ed345efddd", + "zh:f6bbd2b6ee07a47959804e2eeec94cd8b2ac0a90febc322ed87f84efd0e9df4e", + "zh:ff21d2a68c7b63dda5bfacee500943fc6931bdac536b50396fa36d2f07b0177c", + ] +} diff --git a/.ci/infrastructure/main.tf b/.ci/infrastructure/main.tf new file mode 100644 index 0000000..3dac95e --- /dev/null +++ b/.ci/infrastructure/main.tf @@ -0,0 +1,115 @@ +data "aws_caller_identity" "current" {} + +data "github_repository" "coax" { + full_name = "lowobservable/coax" +} + +locals { + # Until there is a aws_iam_openid_connect_provider data source... + github_openid_connect_provider_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/token.actions.githubusercontent.com" +} + +resource "aws_ecr_repository" "icecube2" { + name = "icecube2" + image_tag_mutability = "MUTABLE" + + tags = { + project = "coax" + } +} + +resource "aws_s3_bucket" "cache" { + bucket_prefix = "coax" + acl = "private" + + tags = { + project = "coax" + description = "Cached bitstreams for https://github.com/lowobservable/coax" + } +} + +resource "aws_s3_bucket_policy" "cache" { + bucket = aws_s3_bucket.cache.id + policy = data.aws_iam_policy_document.cache_access.json +} + +data "aws_iam_policy_document" "cache_access" { + statement { + actions = ["s3:ListBucket"] + resources = [aws_s3_bucket.cache.arn] + + principals { + type = "AWS" + identifiers = [aws_iam_role.github_actions.arn] + } + } + + statement { + actions = ["s3:GetObject", "s3:PutObject"] + resources = ["${aws_s3_bucket.cache.arn}/*"] + + principals { + type = "AWS" + identifiers = [aws_iam_role.github_actions.arn] + } + } +} + +resource "aws_iam_role" "github_actions" { + name = "github-actions-coax" + description = "GitHub Actions role for https://github.com/lowobservable/coax" + assume_role_policy = data.aws_iam_policy_document.github_actions_assume_role.json + + tags = { + project = "coax" + } +} + +data "aws_iam_policy_document" "github_actions_assume_role" { + statement { + actions = ["sts:AssumeRoleWithWebIdentity"] + principals { + type = "Federated" + identifiers = [local.github_openid_connect_provider_arn] + } + condition { + test = "StringLike" + variable = "token.actions.githubusercontent.com:sub" + values = ["repo:lowobservable/coax:*"] + } + } +} + +resource "aws_iam_role_policy" "github_actions_access" { + role = aws_iam_role.github_actions.id + policy = data.aws_iam_policy_document.github_actions_access.json +} + +data "aws_iam_policy_document" "github_actions_access" { + statement { + actions = ["ecr:GetAuthorizationToken"] + resources = ["*"] + } + statement { + actions = [ + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability" + ] + resources = [ + aws_ecr_repository.icecube2.arn + ] + } +} + +resource "github_actions_secret" "aws_account_id" { + repository = data.github_repository.coax.name + secret_name = "AWS_ACCOUNT_ID" + plaintext_value = data.aws_caller_identity.current.account_id +} + +resource "github_actions_secret" "aws_iam_role" { + repository = data.github_repository.coax.name + secret_name = "AWS_IAM_ROLE" + plaintext_value = aws_iam_role.github_actions.arn +} diff --git a/.ci/infrastructure/outputs.tf b/.ci/infrastructure/outputs.tf new file mode 100644 index 0000000..3e1a2a8 --- /dev/null +++ b/.ci/infrastructure/outputs.tf @@ -0,0 +1,4 @@ +output "bitstream_cache_bucket" { + value = aws_s3_bucket.cache.id + description = "Use for BITSTREAM_CACHE_BUCKET environment variable" +} diff --git a/.ci/infrastructure/providers.tf b/.ci/infrastructure/providers.tf new file mode 100644 index 0000000..338fcb5 --- /dev/null +++ b/.ci/infrastructure/providers.tf @@ -0,0 +1,5 @@ +provider "aws" { + region = "us-east-1" +} + +provider "github" {} diff --git a/.ci/infrastructure/versions.tf b/.ci/infrastructure/versions.tf new file mode 100644 index 0000000..aa605f0 --- /dev/null +++ b/.ci/infrastructure/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 3.0" + } + + github = { + source = "integrations/github" + version = "~> 4.0" + } + } +}