sd-warning/cloudformation/sd-warning.yaml (164 lines of code) (raw):

AWSTemplateFormatVersion: "2010-09-09" Description: Run minimal Onion site for The Guardian Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Networking Parameters: - VpcId - InstanceSubnet - Label: default: AWS Configuration Parameters: - DataBucketName - AMI - Stage Mappings: Constants: Stack: Value: editorial-systems-development App: Value: sd-warning Parameters: VpcId: Description: ID of the VPC onto which to launch the stack Type: AWS::EC2::VPC::Id InstanceSubnet: Description: Subnet in which the instance will run Type: AWS::EC2::Subnet::Id DataBucketName: Description: Name of the bucket that holds the static site and hidden_service config Type: String AMI: Description: Base AMI for the instance Type: AWS::EC2::Image::Id Stage: Description: Application stage Type: String AllowedValues: - PROD - CODE - DEV Default: PROD Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow HTTP inbound connections VpcId: Ref: VpcId SecurityGroupIngress: - IpProtocol: tcp FromPort: 8080 ToPort: 8080 CidrIp: 127.0.0.1/0 - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 Tags: - Key: Stack Value: Fn::FindInMap: [Constants, Stack, Value] - Key: App Value: Fn::FindInMap: [Constants, App, Value] - Key: Stage Value: !Ref Stage - Key: Name Value: !Sub ${AWS::StackName} InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref InstanceRole InstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / # Minimal policy to run commands via ssm and use ssm-scala SSMRunCommandPolicy: Type: AWS::IAM::Policy Properties: PolicyName: ssm-run-command PolicyDocument: Statement: - Effect: Allow Resource: "*" Action: - ec2messages:AcknowledgeMessage - ec2messages:DeleteMessage - ec2messages:FailMessage - ec2messages:GetEndpoint - ec2messages:GetMessages - ec2messages:SendReply - ssm:UpdateInstanceInformation - ssm:ListInstanceAssociations - ssm:DescribeInstanceProperties - ssm:DescribeDocumentParameters - ssmmessages:CreateControlChannel - ssmmessages:CreateDataChannel - ssmmessages:OpenControlChannel - ssmmessages:OpenDataChannel Roles: - !Ref InstanceRole DataBucketPolicy: Type: AWS::IAM::Policy Properties: PolicyName: bucket-policy PolicyDocument: Statement: - Action: - s3:ListBucket - s3:GetObject Effect: Allow Resource: - !Sub arn:aws:s3:::${DataBucketName} - !Sub arn:aws:s3:::${DataBucketName}/* Roles: - !Ref InstanceRole Instance: Type: "AWS::EC2::Instance" Properties: ImageId: !Ref AMI InstanceType: t3.micro SourceDestCheck: false IamInstanceProfile: !Ref InstanceProfile NetworkInterfaces: - AssociatePublicIpAddress: true DeviceIndex: 0 GroupSet: - Ref: InstanceSecurityGroup SubnetId: Ref: InstanceSubnet Tags: - Key: Name Value: sd-warning UserData: "Fn::Base64": !Sub | #!/bin/bash -ev mkdir -p /www/sd-warning aws s3 cp s3://${DataBucketName}/static/ /www/sd-warning/. --recursive mkdir -p / cat << END > /etc/nginx/sites-enabled/sd-warning server { listen 127.0.0.1:8080; root /www/sd-warning; } END nginx # Copy the key and hostname over to mkdir -p /var/lib/tor/hidden_service aws s3 cp s3://${DataBucketName}/hidden_service/ /var/lib/tor/hidden_service --recursive chmod 700 /var/lib/tor/hidden_service chmod 600 /var/lib/tor/hidden_service/private_key || true # Don't require a private key to be in the s3 bucket echo 'HiddenServiceDir /var/lib/tor/hidden_service/' >> /etc/tor/torrc echo 'HiddenServicePort 80 127.0.0.1:8080' >> /etc/tor/torrc systemctl restart tor.service