Skip to content

Instantly share code, notes, and snippets.

@Warrenn
Last active February 25, 2024 21:28
Show Gist options
  • Save Warrenn/c4686743f465e14aa0d5de2a31bd8a41 to your computer and use it in GitHub Desktop.
Save Warrenn/c4686743f465e14aa0d5de2a31bd8a41 to your computer and use it in GitHub Desktop.
install docker image from ecr
AWSTemplateFormatVersion: "2010-09-09"
Description: Template to deploy funding-arbitrage futures instance
Metadata:
cfn-lint:AWSTemplateFormatVersion: "2010-09-09"
Description: Template to deploy funding-arbitrage futures instance
Metadata:
cfn-lint:
config:
ignore_checks:
- W1001
- E2507
- W3005
- E3002
- E3012
Parameters:
VPCId:
Type: AWS::EC2::VPC::Id
Description: The ID of the VPC
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: The ID of the subnet in the VPC
AmiId:
Description: The name of the AMI id to use for running the funding-arbitrage futures app
Type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>"
Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
ElasticIpAddress:
Description: The IP address of the EC2 instance
Type: String
AllowedPattern: '^(\d{1,3}\.){3}\d{1,3}$'
ConstraintDescription: must be a valid IP address (xxx.xxx.xxx.xxx)
Default: "13.246.141.165"
InstanceType:
Description: The instance type the application will be using
Type: String
Default: t3.micro
RepositoryName:
Type: String
Description: The name of the ecr repository
Default: funding-arbitrage
LogGroupName:
Type: String
Description: The name of the cloudwatch log group used for logging
Default: funding-arbitrage
AppPrefix:
Type: String
Description: The Prefix used generally by the application
Default: funding-arbitrage
EnvName:
Type: String
Description: The environment name
Default: live
Region:
Type: String
Description: The AWS Region for resources
Default: af-south-1
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Disable all ingress access
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: "0.0.0.0/0"
VpcId: !Ref VPCId
SsmVpcEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${Region}.ssm"
VpcId: !Ref VPCId
SubnetIds:
- !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroup
EcrApiEndpoint:
Type: "AWS::EC2::VPCEndpoint"
Properties:
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${Region}.ecr.api"
VpcId: !Ref VPCId
SubnetIds:
- !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroup
EcrDockerEndpoint:
Type: "AWS::EC2::VPCEndpoint"
Properties:
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${Region}.ecr.dkr"
VpcId: !Ref VPCId
SubnetIds:
- !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroup
CloudWatchLogsEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Interface
ServiceName: !Sub "com.amazonaws.${Region}.logs"
VpcId: !Ref VPCId
SubnetIds:
- !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroup
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MaxSize: "1"
MinSize: "0"
DesiredCapacity: "1"
VPCZoneIdentifier:
- !Ref SubnetId
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref InstanceRole
InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: funding-arbitrage-role
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Policies:
- PolicyName: funding-arbitrage-role-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ec2:AssociateAddress
- ec2:DescribeInstances
Resource: "*"
- Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:BatchCheckLayerAvailability
- ecr:DescribeImages
Resource: !Sub "arn:aws:ecr:*:*:repository/${RepositoryName}"
- Effect: Allow
Action:
- ecr:DescribeRepositories
- ecr:GetAuthorizationToken
Resource: "*"
- Effect: Allow
Action:
- logs:DescribeLogGroups
Resource: arn:aws:logs:*:*:*
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- logs:DescribeLogStreams
Resource: !Sub "arn:aws:logs:*:*:log-group:${LogGroupName}:*"
- Effect: Allow
Action:
- autoscaling:*
- cloudwatch:*
- ec2:Describe*
Resource: "*"
- Effect: Allow
Action:
- ssm:GetParametersByPath
- ssm:GetParameters
- ssm:GetParameter
- ssm:ListTagsForResource
Resource:
- arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*
- !Sub "arn:aws:ssm:*:*:parameter/${EnvName}/${AppPrefix}/*"
- !Sub "arn:aws:ssm:*:*:parameter/${EnvName}/${AppPrefix}"
- Effect: Allow
Action:
- kms:Decrypt
Resource:
- arn:aws:kms:*:*:key/alias/aws/ssm
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: funding-arbitrage-launch-template
LaunchTemplateData:
InstanceType: !Ref InstanceType
ImageId: !Ref AmiId
IamInstanceProfile:
Arn: !GetAtt InstanceProfile.Arn
TagSpecifications:
- ResourceType: instance
Tags:
- Key: "Name"
Value: !Sub "${AppPrefix}-instance"
- Key: "env"
Value: !Ref EnvName
NetworkInterfaces:
- DeviceIndex: 0
AssociatePublicIpAddress: true
SubnetId: !Ref SubnetId
Groups:
- !Ref SecurityGroup
DeleteOnTermination: true
UserData:
Fn::Base64: !Sub |
#!/bin/bash -x
yum update -y
yum install -y aws-cli amazon-cloudwatch-agent
amazon-linux-extras install docker
service docker start
usermod -a -G docker ec2-user
chkconfig docker on
mkdir /logs
chmod 777 /logs
cat <<EOF > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent-schema.json
{
"agent": {
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/logs/*",
"log_group_name": "${LogGroupName}",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}
EOF
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent-schema.json
systemctl restart amazon-cloudwatch-agent
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
INSTANCE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id)
aws ec2 associate-address --instance-id ${!INSTANCE_ID} --public-ip ${ElasticIpAddress} --region ${Region} >> /logs/error.log
repositoryUri=$(aws ecr describe-repositories --region ${Region} --query "repositories[?repositoryName=='${RepositoryName}'].repositoryUri" --output text | cut -d'/' -f1)
aws ecr get-login-password --region ${Region} | docker login --username AWS --password-stdin "${!repositoryUri}" 2>> /logs/error.log
docker pull "${!repositoryUri}/${RepositoryName}:latest"
docker run -d \
-v /logs:/logs:rw \
-e CCXT_NODE_REGION="${Region}" \
-e API_CRED_KEY_PREFIX="/${EnvName}/${AppPrefix}/api-credentials/" \
-e TRADE_STATUS_KEY="/${EnvName}/${AppPrefix}/trade-status" \
-e COINGLASS_SECRET_KEY="/${EnvName}/${AppPrefix}/coinglass-secret" \
-e SETTINGS_KEY_PREFIX="/${EnvName}/${AppPrefix}/settings" \
-e TRANSFER_DETAILS_KEY="/${EnvName}/${AppPrefix}/transfer-details" \
-e LOG_GROUP="${LogGroupName}" \
-e LOG_FOLDER="/logs/" \
"${!repositoryUri}/${RepositoryName}:latest" \
npm run start
Outputs:
ScalingGroup:
Value: !Ref AutoScalingGroup
config:
ignore_checks:
- W1001
- E2507
- W3005
- E3002
- E3012
Parameters:
VPCId:
Type: AWS::EC2::VPC::Id
Description: The ID of the VPC
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: The ID of the subnet in the VPC
AmiId:
Description: The name of the AMI id to use for running the funding-arbitrage futures app
Type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>"
Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
InstanceType:
Description: The instance type the application will be using
Type: String
Default: t3.micro
RepositoryName:
Type: String
Description: The name of the ecr repository
Default: funding-arbitrage
LogGroupName:
Type: String
Description: The name of the cloudwatch log group used for logging
Default: funding-arbitrage
AppPrefix:
Type: String
Description: The Prefix used generally by the application
Default: funding-arbitrage
EnvName:
Type: String
Description: The environment name
Default: live
Region:
Type: String
Description: The AWS Region for resources
Default: af-south-1
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Disable all ingress access
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: "0.0.0.0/0"
VpcId: !Ref VPCId
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
MaxSize: "1"
MinSize: "0"
DesiredCapacity: "1"
VPCZoneIdentifier:
- !Ref SubnetId
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref InstanceRole
InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: funding-arbitrage-role
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Policies:
- PolicyName: funding-arbitrage-role-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:BatchCheckLayerAvailability
- ecr:DescribeImages
Resource: !Sub "arn:aws:ecr:*:*:repository/${RepositoryName}"
- Effect: Allow
Action:
- ecr:DescribeRepositories
- ecr:GetAuthorizationToken
Resource: "*"
- Effect: Allow
Action:
- logs:DescribeLogGroups
Resource: arn:aws:logs:*:*:*
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- logs:DescribeLogStreams
Resource: !Sub "arn:aws:logs:*:*:log-group:${LogGroupName}:*"
- Effect: Allow
Action:
- autoscaling:*
- cloudwatch:*
- ec2:Describe*
Resource: "*"
- Effect: Allow
Action:
- ssm:GetParametersByPath
- ssm:GetParameters
- ssm:GetParameter
- ssm:ListTagsForResource
Resource:
- arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*
- !Sub "arn:aws:ssm:*:*:parameter/${EnvName}/${AppPrefix}/*"
- !Sub "arn:aws:ssm:*:*:parameter/${EnvName}/${AppPrefix}"
- Effect: Allow
Action:
- kms:Decrypt
Resource:
- arn:aws:kms:*:*:key/alias/aws/ssm
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: funding-arbitrage-launch-template
LaunchTemplateData:
InstanceType: !Ref InstanceType
ImageId: !Ref AmiId
IamInstanceProfile:
Arn: !GetAtt InstanceProfile.Arn
TagSpecifications:
- ResourceType: instance
Tags:
- Key: "Name"
Value: !Sub "${AppPrefix}-instance"
- Key: "env"
Value: !Ref EnvName
NetworkInterfaces:
- DeviceIndex: 0
AssociatePublicIpAddress: true
SubnetId: !Ref SubnetId
Groups:
- !Ref SecurityGroup
DeleteOnTermination: true
UserData:
Fn::Base64: !Sub |
#!/bin/bash -x
yum update -y
yum install -y aws-cli amazon-cloudwatch-agent
amazon-linux-extras install docker
service docker start
usermod -a -G docker ec2-user
chkconfig docker on
repositoryUri=$(aws ecr describe-repositories --region ${Region} --query "repositories[?repositoryName=='${RepositoryName}'].repositoryUri" --output text | cut -d'/' -f1)
aws ecr get-login-password --region ${Region} | docker login --username AWS --password-stdin "${!repositoryUri}"
mkdir /logs
chmod 665 /logs
docker pull "${!repositoryUri}/${RepositoryName}:latest"
docker run -d \
-v /logs:/logs \
-e CCXT_NODE_REGION="${Region}" \
-e API_CRED_KEY_PREFIX="/${EnvName}/${AppPrefix}/api-credentials/" \
-e TRADE_STATUS_KEY="/${EnvName}/${AppPrefix}/trade-status" \
-e COINGLASS_SECRET_KEY="/${EnvName}/${AppPrefix}/coinglass-secret" \
-e SETTINGS_KEY_PREFIX="/${EnvName}/${AppPrefix}/settings" \
-e TRANSFER_DETAILS_KEY="/${EnvName}/${AppPrefix}/transfer-details" \
-e LOG_GROUP="${LogGroupName}" \
-e LOG_FOLDER="/logs/" \
"${!repositoryUri}/${RepositoryName}:latest"
cat <<EOF > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent-schema.json
{
"agent": {
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/logs/*",
"log_group_name": "${LogGroupName}",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}
EOF
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent-schema.json
systemctl restart amazon-cloudwatch-agent
Outputs:
ScalingGroup:
Value: !Ref AutoScalingGroup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment