From 3e4695ba5ae1601678b43e481c65b6e08ac0c38f Mon Sep 17 00:00:00 2001 From: Chris Patti Date: Wed, 8 Feb 2023 15:37:12 -0500 Subject: [PATCH] Initial stab at fixing #1090 --- .../Pulumi.applications.micromasters.QA.yaml | 15 ++ .../applications/micromasters/Pulumi.yaml | 7 + .../applications/micromasters/__main__.py | 184 ++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 src/ol_infrastructure/applications/micromasters/Pulumi.applications.micromasters.QA.yaml create mode 100644 src/ol_infrastructure/applications/micromasters/Pulumi.yaml create mode 100644 src/ol_infrastructure/applications/micromasters/__main__.py diff --git a/src/ol_infrastructure/applications/micromasters/Pulumi.applications.micromasters.QA.yaml b/src/ol_infrastructure/applications/micromasters/Pulumi.applications.micromasters.QA.yaml new file mode 100644 index 0000000000..1584ca2650 --- /dev/null +++ b/src/ol_infrastructure/applications/micromasters/Pulumi.applications.micromasters.QA.yaml @@ -0,0 +1,15 @@ +--- +secretsprovider: awskms://alias/infrastructure-secrets-qa +encryptedkey: AQICAHijXuVxVlAL6bY9xCOrzO3YYhFlQBPt6jNyJGkhYu+q4QEsTzqLr3gfTn1G3A6pkrEbAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM1rdw6SA8KJIVsrqgAgEQgDtFgUTp7OitAkIB79LlqX1C9uN9VEph+bqsa1Q0VNT1TP0pqNpCo2rzs7zmr3iUcvpAMn/1Y4q9TNPmHg== +config: + aws:region: us-east-1 + consul:address: https://consul-micromasters-qa.odl.mit.edu + consul:http_auth: + secure: v1:cFN5rfbLYKJOLKko:EbolfR0aA+3QNuLKU4ixNwZVdSuSB5UIl0gAPICG4mrprmQSDFabC/VkxrJGDgaAbELMxpskbvN0qj2y9SMX0IlKJYD2JHUZsfYqd8FX1QcxAxeSL00jJ5Zkks+mP8c= + consul:scheme: https + micromasters:db_password: + secure: v1:72AVczMFP7U0adTg:qiVKioH1VjNf38HfLkNIZsCdc8RqKs0bkaou+fU6SSRK9W4kbS1do2PwdD3JWYlc37eojd+sdAL8npp+tyEeQ66q5mHmWDQK3WlqgdWbf8G41fizyMwoy2AQdZmtZtJe40IoeqaSX3ntfJvhI0uP7YWmpge4G9e6KMNBmhZ0wl0T6qHU4z180aId1ZpjCM4= + micromasters:domain: rc.micromasters.mit.edu + micromasters:proctortrack_url: https://preproduction.verificient.com + vault:address: https://vault-qa.odl.mit.edu + vault_server:env_namespace: operations.qa diff --git a/src/ol_infrastructure/applications/micromasters/Pulumi.yaml b/src/ol_infrastructure/applications/micromasters/Pulumi.yaml new file mode 100644 index 0000000000..f50fbc4109 --- /dev/null +++ b/src/ol_infrastructure/applications/micromasters/Pulumi.yaml @@ -0,0 +1,7 @@ +--- +name: ol-infrastructure-micromasters-application +runtime: python +description: Pulumi project for deploying the stack of services needed by the micromasters + application +backend: + url: s3://mitol-pulumi-state/ diff --git a/src/ol_infrastructure/applications/micromasters/__main__.py b/src/ol_infrastructure/applications/micromasters/__main__.py new file mode 100644 index 0000000000..98120e356c --- /dev/null +++ b/src/ol_infrastructure/applications/micromasters/__main__.py @@ -0,0 +1,184 @@ +"""Create the infrastructure and services needed to support the MicroMasters application. + +- Create a PostgreSQL database in AWS RDS for production environments +- Create an IAM policy to grant access to S3 and other resources +""" + +import json + +import pulumi_consul as consul +import pulumi_vault as vault +from pulumi import Config, StackReference, export +from pulumi_aws import ec2, iam, s3 + +from bridge.lib.magic_numbers import DEFAULT_POSTGRES_PORT +from ol_infrastructure.components.aws.database import OLAmazonDB, OLPostgresDBConfig +from ol_infrastructure.components.services.vault import ( + OLVaultDatabaseBackend, + OLVaultPostgresDatabaseConfig, +) +from ol_infrastructure.lib.aws.iam_helper import lint_iam_policy +from ol_infrastructure.lib.ol_types import AWSBase +from ol_infrastructure.lib.pulumi_helper import parse_stack +from ol_infrastructure.lib.stack_defaults import defaults +from ol_infrastructure.lib.vault import setup_vault_provider + +setup_vault_provider() +micromasters_config = Config("micromasters") +stack_info = parse_stack() +network_stack = StackReference(f"infrastructure.aws.network.{stack_info.name}") +micromasters_vpc = network_stack.require_output("micromasters_vpc") +operations_vpc = network_stack.require_output("operations_vpc") +micromasters_environment = f"micromasters-{stack_info.env_suffix}" +aws_config = AWSBase( + tags={ + "OU": "micromasters", + "Environment": micromasters_environment, + "Application": "micromasters", + } +) + +# Create S3 bucket + +# Bucket used to store files from MicroMasters app. +micromasters_bucket_name = f"ol-micromasters-app-{stack_info.env_suffix}" +micromasters_bucket = s3.Bucket( + f"micromasters-{stack_info.env_suffix}", + bucket=micromasters_bucket_name, + versioning=s3.BucketVersioningArgs( + enabled=True, + ), + tags=aws_config.tags, + acl="public-read", + policy=json.dumps( + { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "PublicRead", + "Effect": "Allow", + "Principal": "*", + "Action": ["s3:GetObject"], + "Resource": [f"arn:aws:s3:::{micromasters_bucket_name}/*"], + } + ], + } + ), + cors_rules=[{"allowedMethods": ["GET", "HEAD"], "allowedOrigins": ["*"]}], +) + + +micromasters_iam_policy = iam.Policy( + f"micromasters-{stack_info.env_suffix}-policy", + description="AWS access controls for the MicroMasters application in the " + f"{stack_info.name} environment", + path=f"/ol-applications/micromasters/{stack_info.env_suffix}/", + name_prefix=f"micromasters-{stack_info.env_suffix}-application-policy-", + policy=lint_iam_policy( + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:ListAllMyBuckets", + "Resource": "*", + }, + { + "Effect": "Allow", + "Action": [ + "s3:ListBucket*", + "s3:PutObject", + "s3:PutObjectAcl", + "s3:GetObject*", + "s3:DeleteObject*", + ], + "Resource": [ + f"arn:aws:s3:::{micromasters_bucket_name}", + f"arn:aws:s3:::{micromasters_bucket_name}/*", + ], + }, + ], + }, + stringify=True, + parliament_config={ + "PERMISSIONS_MANAGEMENT_ACTIONS": { + "ignore_locations": [{"actions": ["s3:putobjectacl"]}] + } + }, + ), +) + +micromasters_vault_backend_role = vault.aws.SecretBackendRole( + "micromasters-app", + name="micromasters", + backend="aws-micromasters", + credential_type="iam_user", + policy_arns=[micromasters_iam_policy.arn], +) + +# Create RDS instance +micromasters_db_security_group = ec2.SecurityGroup( + f"micromasters-db-access-{stack_info.env_suffix}", + description=f"Access control for the MicroMasters App DB in {stack_info.name}", + ingress=[ + ec2.SecurityGroupIngressArgs( + protocol="tcp", + from_port=DEFAULT_POSTGRES_PORT, + to_port=DEFAULT_POSTGRES_PORT, + cidr_blocks=["0.0.0.0/0"], + ipv6_cidr_blocks=["::/0"], + description="Allow access over the public internet from Heroku", + ) + ], + egress=[ + ec2.SecurityGroupEgressArgs( + from_port=0, + to_port=0, + protocol="-1", + cidr_blocks=["0.0.0.0/0"], + ipv6_cidr_blocks=["::/0"], + ) + ], + tags=aws_config.merged_tags( + {"Name": "micromasters-db-access-applications-{stack_info.env_suffix}"} + ), + vpc_id=micromasters_vpc["id"], +) + +micromasters_db_config = OLPostgresDBConfig( + instance_name=f"micromasters-{stack_info.env_suffix}-app-db", + password=micromasters_config.require("db_password"), + subnet_group_name=micromasters_vpc["rds_subnet"], + security_groups=[micromasters_db_security_group], + tags=aws_config.tags, + db_name="micromasters", + public_access=True, + **defaults(stack_info)["rds"], +) +micromasters_db = OLAmazonDB(micromasters_db_config) + +micromasters_vault_backend_config = OLVaultPostgresDatabaseConfig( + db_name=micromasters_db_config.db_name, + mount_point=f"{micromasters_db_config.engine}-micromasters", + db_admin_username=micromasters_db_config.username, + db_admin_password=micromasters_db_config.password.get_secret_value(), + db_host=micromasters_db.db_instance.address, +) +micromasters_vault_backend = OLVaultDatabaseBackend(micromasters_vault_backend_config) + +# Set Consul key for use in edxapp configuration template +consul.Keys( + "micromasters-app-domain-for-edxapp", + keys=[ + consul.KeysKeyArgs( + path="edxapp/marketing-domain", + value=micromasters_config.require("domain"), + ), + consul.KeysKeyArgs( + path="edxapp/proctortrack-base-url", + value=micromasters_config.require("proctortrack_url"), + ), + ], +) + +export("micromasters_app", {"rds_host": micromasters_db.db_instance.address})