1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-06 23:46:29 +02:00

checkpoint

This commit is contained in:
Lee Brown 2019-07-10 00:17:35 -08:00
parent 6851b96a04
commit 1de40e048d
11 changed files with 1226 additions and 176 deletions

View File

@ -53,6 +53,8 @@ COPY --from=builder /gosrv /
#COPY --from=builder /static /static #COPY --from=builder /static /static
COPY --from=builder /templates /templates COPY --from=builder /templates /templates
ENV TEMPLATE_DIR=/templates
ARG service ARG service
ENV SERVICE_NAME $service ENV SERVICE_NAME $service

View File

@ -23,14 +23,39 @@
"containerPort": 80 "containerPort": 80
} }
], ],
"cpu": 768, "cpu": 128,
"memoryReservation": 2560, "memoryReservation": 128,
"volumesFrom": [], "volumesFrom": [],
"environment": [ "environment": [
{"name": "AWS_ACCESS_KEY_ID", "value": "-"},
{"name": "AWS_SECRET_ACCESS_KEY", "value": "-"},
{"name": "AWS_REGION", "value": "{AWS_REGION}"},
{"name": "AWS_USE_ROLE", "value": "true"},
{"name": "AWSLOGS_GROUP", "value": "{AWSLOGS_GROUP}"}, {"name": "AWSLOGS_GROUP", "value": "{AWSLOGS_GROUP}"},
{"name": "ECS_CLUSTER", "value": "{ECS_CLUSTER}"}, {"name": "ECS_CLUSTER", "value": "{ECS_CLUSTER}"},
{"name": "ECS_SERVICE", "value": "{ECS_SERVICE}"}, {"name": "ECS_SERVICE", "value": "{ECS_SERVICE}"},
{"name": "HAS_LB", "value": "{HAS_LB}"}, {"name": "WEB_API_HTTP_HOST", "value": "{HTTP_HOST}"},
{"name": "WEB_API_HTTPS_HOST", "value": "{HTTPS_HOST}"},
{"name": "WEB_API_APP_BASE_URL", "value": "{APP_BASE_URL}"},
{"name": "WEB_API_REDIS_HOST", "value": "{CACHE_HOST}"},
{"name": "WEB_API_DB_HOST", "value": "{DB_HOST}"},
{"name": "WEB_API_DB_USER", "value": "{DB_USER}"},
{"name": "WEB_API_DB_PASS", "value": "{DB_PASS}"},
{"name": "WEB_API_DB_DATABASE", "value": "{DB_DATABASE}"},
{"name": "WEB_API_DB_DRIVER", "value": "{DB_DRIVER}"},
{"name": "WEB_API_DB_DISABLE_TLS", "value": "{DB_DISABLE_TLS}"},
{"name": "WEB_API_AUTH_USE_AWS_SECRET_MANAGER", "value": "true"},
{"name": "WEB_API_AUTH_AWS_SECRET_ID", "value": "auth-{ECS_SERVICE}"},
{"name": "BUILDINFO_CI_COMMIT_REF_NAME", "value": "{CI_COMMIT_REF_NAME}"},
{"name": "BUILDINFO_CI_COMMIT_REF_SLUG", "value": "{CI_COMMIT_REF_SLUG}"},
{"name": "BUILDINFO_CI_COMMIT_SHA", "value": "{CI_COMMIT_SHA}"},
{"name": "BUILDINFO_CI_COMMIT_TAG", "value": "{CI_COMMIT_TAG}"},
{"name": "BUILDINFO_CI_COMMIT_TITLE", "value": "{CI_COMMIT_TITLE}"},
{"name": "BUILDINFO_CI_COMMIT_DESCRIPTION", "value": "{CI_COMMIT_DESCRIPTION}"},
{"name": "BUILDINFO_CI_COMMIT_JOB_ID", "value": "{CI_COMMIT_JOB_ID}"},
{"name": "BUILDINFO_CI_COMMIT_JOB_URL", "value": "{CI_COMMIT_JOB_URL}"},
{"name": "BUILDINFO_CI_COMMIT_PIPELINE_ID", "value": "{CI_COMMIT_PIPELINE_ID}"},
{"name": "BUILDINFO_CI_COMMIT_PIPELINE_URL", "value": "{CI_COMMIT_PIPELINE_URL}"},
{"name": "DATADOG_ADDR", "value": "127.0.0.1:8125"}, {"name": "DATADOG_ADDR", "value": "127.0.0.1:8125"},
{"name": "DD_TRACE_AGENT_HOSTNAME", "value": "127.0.0.1"}, {"name": "DD_TRACE_AGENT_HOSTNAME", "value": "127.0.0.1"},
{"name": "DD_TRACE_AGENT_PORT", "value": "8126"}, {"name": "DD_TRACE_AGENT_PORT", "value": "8126"},
@ -63,10 +88,10 @@
}, },
{ {
"name": "datadog-agent", "name": "datadog-agent",
"image": "421734222910.dkr.ecr.us-west-2.amazonaws.com/procedures:datadog-agent", "image": "datadog/agent:latest",
"essential": true, "essential": {DATADOG_ESSENTIAL},
"cpu": 256, "cpu": 128,
"memoryReservation": 512, "memoryReservation": 128,
"portMappings": [ "portMappings": [
{ {
"containerPort": 8125 "containerPort": 8125

View File

@ -150,6 +150,12 @@ func main() {
// ========================================================================= // =========================================================================
// Config Validation & Defaults // Config Validation & Defaults
// AWS access keys are required, if roles are enabled, remove any placeholders.
if cfg.Aws.UseRole {
cfg.Aws.AccessKeyID = ""
cfg.Aws.SecretAccessKey = ""
}
// If base URL is empty, set the default value from the HTTP Host // If base URL is empty, set the default value from the HTTP Host
if cfg.App.BaseUrl == "" { if cfg.App.BaseUrl == "" {
baseUrl := cfg.HTTP.Host baseUrl := cfg.HTTP.Host
@ -220,16 +226,14 @@ func main() {
// default not set and will based on the redis config values defined on the server // default not set and will based on the redis config values defined on the server
if cfg.Redis.MaxmemoryPolicy != "" { if cfg.Redis.MaxmemoryPolicy != "" {
err := redisClient.ConfigSet(evictPolicyConfigKey, cfg.Redis.MaxmemoryPolicy).Err() err := redisClient.ConfigSet(evictPolicyConfigKey, cfg.Redis.MaxmemoryPolicy).Err()
if err != nil { if err != nil && !strings.Contains(err.Error(), "unknown command") {
log.Fatalf("main : redis : ConfigSet maxmemory-policy : %v", err) log.Fatalf("main : redis : ConfigSet maxmemory-policy : %v", err)
} }
} else { } else {
evictPolicy, err := redisClient.ConfigGet(evictPolicyConfigKey).Result() evictPolicy, err := redisClient.ConfigGet(evictPolicyConfigKey).Result()
if err != nil { if err != nil && !strings.Contains(err.Error(), "unknown command") {
log.Fatalf("main : redis : ConfigGet maxmemory-policy : %v", err) log.Fatalf("main : redis : ConfigGet maxmemory-policy : %v", err)
} } else if evictPolicy != nil && len(evictPolicy) > 0 && evictPolicy[1] != "allkeys-lru" {
if evictPolicy[1] != "allkeys-lru" {
log.Printf("main : redis : ConfigGet maxmemory-policy : recommended to be set to allkeys-lru to avoid OOM") log.Printf("main : redis : ConfigGet maxmemory-policy : recommended to be set to allkeys-lru to avoid OOM")
} }
} }

View File

@ -37,6 +37,8 @@ COPY --from=builder /gosrv /
COPY --from=builder /static /static COPY --from=builder /static /static
COPY --from=builder /templates /templates COPY --from=builder /templates /templates
ENV TEMPLATE_DIR=/templates
ARG service ARG service
ENV SERVICE_NAME $service ENV SERVICE_NAME $service

View File

@ -146,6 +146,12 @@ func main() {
// ========================================================================= // =========================================================================
// Config Validation & Defaults // Config Validation & Defaults
// AWS access keys are required, if roles are enabled, remove any placeholders.
if cfg.Aws.UseRole {
cfg.Aws.AccessKeyID = ""
cfg.Aws.SecretAccessKey = ""
}
// If base URL is empty, set the default value from the HTTP Host // If base URL is empty, set the default value from the HTTP Host
if cfg.App.BaseUrl == "" { if cfg.App.BaseUrl == "" {
baseUrl := cfg.HTTP.Host baseUrl := cfg.HTTP.Host
@ -216,16 +222,14 @@ func main() {
// default not set and will based on the redis config values defined on the server // default not set and will based on the redis config values defined on the server
if cfg.Redis.MaxmemoryPolicy != "" { if cfg.Redis.MaxmemoryPolicy != "" {
err := redisClient.ConfigSet(evictPolicyConfigKey, cfg.Redis.MaxmemoryPolicy).Err() err := redisClient.ConfigSet(evictPolicyConfigKey, cfg.Redis.MaxmemoryPolicy).Err()
if err != nil { if err != nil && !strings.Contains(err.Error(), "unknown command") {
log.Fatalf("main : redis : ConfigSet maxmemory-policy : %v", err) log.Fatalf("main : redis : ConfigSet maxmemory-policy : %v", err)
} }
} else { } else {
evictPolicy, err := redisClient.ConfigGet(evictPolicyConfigKey).Result() evictPolicy, err := redisClient.ConfigGet(evictPolicyConfigKey).Result()
if err != nil { if err != nil && !strings.Contains(err.Error(), "unknown command") {
log.Fatalf("main : redis : ConfigGet maxmemory-policy : %v", err) log.Fatalf("main : redis : ConfigGet maxmemory-policy : %v", err)
} } else if evictPolicy != nil && len(evictPolicy) > 0 && evictPolicy[1] != "allkeys-lru" {
if evictPolicy[1] != "allkeys-lru" {
log.Printf("main : redis : ConfigGet maxmemory-policy : recommended to be set to allkeys-lru to avoid OOM") log.Printf("main : redis : ConfigGet maxmemory-policy : recommended to be set to allkeys-lru to avoid OOM")
} }
} }

View File

@ -3,6 +3,7 @@ module geeks-accelerator/oss/saas-starter-kit/example-project
require ( require (
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
github.com/aws/aws-sdk-go v1.20.16 github.com/aws/aws-sdk-go v1.20.16
github.com/bobesa/go-domain-util v0.0.0-20180815122459-1d708c097a6a
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dimfeld/httptreemux v5.0.1+incompatible github.com/dimfeld/httptreemux v5.0.1+incompatible

View File

@ -14,6 +14,7 @@ github.com/aws/aws-sdk-go v1.20.15 h1:y9ts8MJhB7ReUidS6Rq+0KxdFeL01J+pmOlGq6Yqpi
github.com/aws/aws-sdk-go v1.20.15/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.20.15/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.20.16 h1:Dq68fBH39XnSjjb2hX/iW6mui8JtXcVAuhRYGSRiisY= github.com/aws/aws-sdk-go v1.20.16 h1:Dq68fBH39XnSjjb2hX/iW6mui8JtXcVAuhRYGSRiisY=
github.com/aws/aws-sdk-go v1.20.16/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.20.16/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/bobesa/go-domain-util v0.0.0-20180815122459-1d708c097a6a/go.mod h1:/mf0HzRK9xVv+1puqGSMzCo7bhEcQhiisuUXlMkq2p4=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=

View File

@ -15,6 +15,12 @@
"ec2:DescribeSecurityGroups", "ec2:DescribeSecurityGroups",
"ec2:CreateSecurityGroup", "ec2:CreateSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress", "ec2:AuthorizeSecurityGroupIngress",
"elasticache:DescribeCacheClusters",
"elasticache:CreateCacheCluster",
"elasticache:DescribeCacheParameterGroups",
"elasticache:CreateCacheParameterGroup",
"elasticache:ModifyCacheCluster",
"elasticache:ModifyCacheParameterGroup",
"elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:CreateLoadBalancer", "elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DescribeTargetGroups",
@ -28,12 +34,16 @@
"ecs:UpdateService", "ecs:UpdateService",
"ecs:RegisterTaskDefinition", "ecs:RegisterTaskDefinition",
"ecs:ListTaskDefinitions", "ecs:ListTaskDefinitions",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchDeleteImage", "ecr:BatchDeleteImage",
"ecr:GetAuthorizationToken", "ecr:GetAuthorizationToken",
"ecr:DescribeImages", "ecr:DescribeImages",
"ecr:DescribeRepositories", "ecr:DescribeRepositories",
"ecs:DescribeTasks",
"ecr:CreateRepository", "ecr:CreateRepository",
"ecr:ListImages", "ecr:ListImages",
"ecs:ListTasks",
"ecr:PutImage",
"ecr:InitiateLayerUpload", "ecr:InitiateLayerUpload",
"ecr:UploadLayerPart", "ecr:UploadLayerPart",
"ecr:CompleteLayerUpload", "ecr:CompleteLayerUpload",
@ -54,6 +64,24 @@
"iam:ListPolicies", "iam:ListPolicies",
"iam:GetPolicyVersion", "iam:GetPolicyVersion",
"iam:CreatePolicyVersion", "iam:CreatePolicyVersion",
"logs:DescribeLogStreams",
"logs:CreateExportTask",
"logs:DescribeExportTasks",
"s3:CreateBucket",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketAcl",
"s3:HeadBucket",
"s3:ListObjects",
"s3:ListBucket",
"s3:GetObject",
"s3:PutLifecycleConfiguration",
"s3:PutBucketCORS",
"s3:PutBucketPolicy",
"s3:PutBucketPublicAccessBlock",
"route53:CreateHostedZone",
"route53:ListHostedZones",
"secretsmanager:ListSecrets", "secretsmanager:ListSecrets",
"secretsmanager:GetSecretValue" "secretsmanager:GetSecretValue"
], ],

View File

@ -1,6 +1,7 @@
package devops package devops
import ( import (
"github.com/aws/aws-sdk-go/service/elasticache"
"strings" "strings"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
@ -20,6 +21,9 @@ type ServiceDeployFlags struct {
EnableHTTPS bool `validate:"omitempty" example:"false"` EnableHTTPS bool `validate:"omitempty" example:"false"`
ServiceDomainName string `validate:"omitempty" example:"example-project.com"` ServiceDomainName string `validate:"omitempty" example:"example-project.com"`
ServiceDomainNameAliases cli.StringSlice `validate:"omitempty" example:"subdomain.example-project.com"` ServiceDomainNameAliases cli.StringSlice `validate:"omitempty" example:"subdomain.example-project.com"`
S3BucketPrivateName string `validate:"omitempty" example:"saas-example-project-private"`
S3BucketPublicName string `validate:"omitempty" example:"saas-example-project-public"`
ProjectRoot string `validate:"omitempty" example:"."` ProjectRoot string `validate:"omitempty" example:"."`
ProjectName string ` validate:"omitempty" example:"example-project"` ProjectName string ` validate:"omitempty" example:"example-project"`
DockerFile string `validate:"omitempty" example:"./cmd/web-api/Dockerfile"` DockerFile string `validate:"omitempty" example:"./cmd/web-api/Dockerfile"`
@ -52,12 +56,15 @@ type serviceDeployRequest struct {
EcsServiceDesiredCount int64 `validate:"required"` EcsServiceDesiredCount int64 `validate:"required"`
Ec2SecurityGroupName string `validate:"required"` Ec2SecurityGroupName string `validate:"required"`
CloudWatchLogGroupName string `validate:"required"` CloudWatchLogGroupName string `validate:"required"`
S3BucketTempPrefix string `validate:"required"`
AwsCreds awsCredentials `validate:"required,dive,required"` AwsCreds awsCredentials `validate:"required,dive,required"`
// Optional flags. // Optional flags.
EnableHTTPS bool `validate:"omitempty"` EnableHTTPS bool `validate:"omitempty"`
ServiceDomainName string `validate:"omitempty,required_with=EnableHTTPS,fqdn"` ServiceDomainName string `validate:"omitempty,required_with=EnableHTTPS,fqdn"`
ServiceDomainNameAliases []string `validate:"omitempty,dive,fqdn"` ServiceDomainNameAliases []string `validate:"omitempty,dive,fqdn"`
S3BucketPrivateName string `validate:"omitempty"`
S3BucketPublicName string `validate:"omitempty"`
EcrRepositoryMaxImages int `validate:"omitempty"` EcrRepositoryMaxImages int `validate:"omitempty"`
EcsServiceMinimumHealthyPercent *int64 `validate:"omitempty"` EcsServiceMinimumHealthyPercent *int64 `validate:"omitempty"`
EcsServiceMaximumPercent *int64 `validate:"omitempty"` EcsServiceMaximumPercent *int64 `validate:"omitempty"`
@ -72,6 +79,7 @@ type serviceDeployRequest struct {
NoPush bool `validate:"omitempty"` NoPush bool `validate:"omitempty"`
RecreateService bool `validate:"omitempty"` RecreateService bool `validate:"omitempty"`
CacheCluster *elasticache.CreateCacheClusterInput
ReleaseImage string ReleaseImage string
BuildTags []string BuildTags []string
flags ServiceDeployFlags flags ServiceDeployFlags

File diff suppressed because it is too large Load Diff

View File

@ -218,6 +218,8 @@ func main() {
cli.BoolFlag{Name: "enable_https", Usage: "enable HTTPS", Destination: &deployFlags.EnableHTTPS}, cli.BoolFlag{Name: "enable_https", Usage: "enable HTTPS", Destination: &deployFlags.EnableHTTPS},
cli.StringFlag{Name: "domain_name", Usage: "dev, stage, or prod", Destination: &deployFlags.ServiceDomainName}, cli.StringFlag{Name: "domain_name", Usage: "dev, stage, or prod", Destination: &deployFlags.ServiceDomainName},
cli.StringSliceFlag{Name: "domain_name_aliases", Usage: "dev, stage, or prod", Value: &deployFlags.ServiceDomainNameAliases}, cli.StringSliceFlag{Name: "domain_name_aliases", Usage: "dev, stage, or prod", Value: &deployFlags.ServiceDomainNameAliases},
cli.StringFlag{Name: "private_bucket", Usage: "dev, stage, or prod", Destination: &deployFlags.S3BucketPrivateName},
cli.StringFlag{Name: "public_bucket", Usage: "dev, stage, or prod", Destination: &deployFlags.S3BucketPublicName},
cli.StringFlag{Name: "dockerfile", Usage: "DockerFile for service", Destination: &deployFlags.DockerFile}, cli.StringFlag{Name: "dockerfile", Usage: "DockerFile for service", Destination: &deployFlags.DockerFile},
cli.StringFlag{Name: "root", Usage: "project root directory", Destination: &deployFlags.ProjectRoot}, cli.StringFlag{Name: "root", Usage: "project root directory", Destination: &deployFlags.ProjectRoot},
cli.StringFlag{Name: "project", Usage: "name of project", Destination: &deployFlags.ProjectName}, cli.StringFlag{Name: "project", Usage: "name of project", Destination: &deployFlags.ProjectName},