Skip to content

Commit

Permalink
Added CloudFormation
Browse files Browse the repository at this point in the history
  • Loading branch information
cruizba committed Nov 22, 2019
1 parent b6aeb46 commit 950c118
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 5 deletions.
225 changes: 225 additions & 0 deletions CF_spring_cloud_aws_sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
AWSTemplateFormatVersion: 2010-09-09
Description: AWS Cloud Formation Spring Cloud Aws Example

Parameters:

DatabasePassword:
Description: Database Password
Type: String
NoEcho: true
Default: your_password

KeyName:
Description: "Name of an existing EC2 KeyPair to enable SSH access to the instance."
Type: AWS::EC2::KeyPair::KeyName
ConstraintDescription: "must be the name of an existing EC2 KeyPair."

Mappings:
RegionMap:
eu-west-1:
AMI: ami-02df9ea15c1778c9c

Resources:

SpringCloudAwsRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: SpringCloudAwsRolePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'rds:DescribeDBInstances'
- 's3:PutObject'
- 's3:GetObject'
- 's3:DeleteObject'
- 'secretsmanager:DescribeSecret'
- 'secretsmanager:GetSecretValue'
- 'secretsmanager:ListSecrets'
- 'secretsmanager:ListSecretVersionIds'

Resource: '*'
RoleName: SpringCloudAwsSampleRole

SpringCloudAwsInstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
DependsOn: SpringCloudAwsRole
Properties:
Path: /
Roles:
- SpringCloudAwsSampleRole

SpringCloudAwsRDS:
Type: AWS::RDS::DBInstance
DependsOn:
- SpringCloudAwsRole
Properties:
AllocatedStorage: '5'
DBInstanceIdentifier: springaws
DBInstanceClass: db.t2.micro
Engine: MySQL
DBName: springaws
MasterUsername: springaws
MasterUserPassword: !Ref DatabasePassword
MultiAZ: false
PubliclyAccessible: true
DBSecurityGroups:
- !Ref SpringCloudAwsRDSSecurityGroup
DeletionPolicy: Delete

SpringCloudAwsRDSSecurityGroup:
Type: AWS::RDS::DBSecurityGroup
Properties:
GroupDescription : Security Group for RDS public Access
DBSecurityGroupIngress:
- CIDRIP: 0.0.0.0/0

SpringCloudAwsServerSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Security Group for Spring server
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
CidrIp: 0.0.0.0/0

S3bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: spring-cloud-aws-sample-s3
DeletionPolicy: Delete

BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
DependsOn: S3bucket
Properties:
Bucket: 'spring-cloud-aws-sample-s3'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: 'AddPerm'
Principal: '*'
Action: 's3:GetObject'
Effect: 'Allow'
Resource:
- 'arn:aws:s3:::spring-cloud-aws-sample-s3/*'

SpringCloudAwsEC2Instance:
Type: AWS::EC2::Instance
Metadata:
Comment: Spring Using AWS services
AWS::CloudFormation::Init:
config:
files:
"/etc/cfn/cfn-hup.conf":
content: !Sub |
[main]
stack=${AWS::StackId}
region=${AWS::Region}
mode: "000400"
owner: "root"
group: "root"
"/etc/cfn/hooks.d/cfn-auto-reloader.conf":
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.SpringCloudAwsEC2Instance.Metadata.AWS::CloudFormation::Init
action=/usr/local/bin/cfn-init -v --stack ${AWS::StackName} --resource SpringCloudAwsEC2Instance --region ${AWS::Region}
mode: "000400"
owner: "root"
group: "root"
"/usr/local/bin/installSoftware.sh":
content: |
#!/bin/bash -xe
set -eu -o pipefail
# installing necessary software
apt-get update
apt-get install -y awscli python-pip
pip install --upgrade awscli
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
apt-get update
apt-get install -y docker-ce
mode: "000755"
owner: "root"
group: "root"
"/usr/local/bin/check_app_ready.sh":
content: |
#!/bin/bash -xe
set -eu -o pipefail
sleep 1m
while true
do
HTTP_STATUS=$(curl -Ik http://localhost/ | head -n1 | awk '{print $2}')
if [ $HTTP_STATUS == 200 ]; then
break
fi
sleep 1
done
mode: "000755"
owner: "root"
group: "root"
Properties:
ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI]
InstanceType: t2.micro
KeyName: !Ref KeyName
IamInstanceProfile: !Ref SpringCloudAwsInstanceProfile
SecurityGroupIds:
- !GetAtt 'SpringCloudAwsServerSecurityGroup.GroupId'
Tags:
- Key: Name
Value: 'spring-aws-cloud-sample'
UserData:
"Fn::Base64":
!Sub |
#!/bin/bash -xe
set -eu -o pipefail
apt-get update
apt-get install -y python-pip
pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz

cfn-init --region ${AWS::Region} --stack ${AWS::StackId} --resource SpringCloudAwsEC2Instance

# Install needed software
/usr/local/bin/installSoftware.sh || { echo "Error installing software"; exit 1; }

# Run App
docker run -e PROG_OPTS='--spring.profiles.active=prod' -p 80:8080 codeurjc/spring-cloud-aws-sample:latest

/usr/local/bin/check_app_ready.sh || { echo "Error installing software"; exit 1; }

# sending the finish call
/usr/local/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource WaitCondition --region ${AWS::Region}

WaitCondition:
Type: AWS::CloudFormation::WaitCondition
CreationPolicy:
ResourceSignal:
Timeout: PT40M
Count: 1

Outputs:
Application:
Description: "Deployed Spring Application"
Value: !Join
- ''
- - 'http://'
- !GetAtt SpringCloudAwsEC2Instance.PublicDnsName
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Then, create an RDS instance, with these properties:

### Create an S3 bucket

Create an S3 bucket, name it `spring-cloud-aws-sample` and give read permissions to anonymous users. Just copy and paste this aws policy to enable anonymous read access:
Create an S3 bucket, name it `spring-cloud-aws-sample-s3` and give read permissions to anonymous users. Just copy and paste this aws policy to enable anonymous read access:

{
"Version":"2012-10-17",
Expand All @@ -45,7 +45,7 @@ Create an S3 bucket, name it `spring-cloud-aws-sample` and give read permissions
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::spring-cloud-aws-sample/*"]
"Resource":["arn:aws:s3:::spring-cloud-aws-sample-s3/*"]
}
]
}
Expand All @@ -64,7 +64,7 @@ Create a new secret named as: `/secrets-app/springaws_prod`. You can insert your

### To run locally

Some configurations are required in your AWS account for this sample to work. Basically, an _S3 bucket_ (by default `spring-cloud-aws-sample` is used, but it can be changed using `cloud.aws.s3.bucket` property), and an _RDS MySQL instance_ open to the world. Additionally, we need an _IAM user_ with access key and programmatic access to AWS API so that we can access AWS resources from our development machine.
Some configurations are required in your AWS account for this sample to work. Basically, an _S3 bucket_ (by default `spring-cloud-aws-sample-s3` is used, but it can be changed using `cloud.aws.s3.bucket` property), and an _RDS MySQL instance_ open to the world. Additionally, we need an _IAM user_ with access key and programmatic access to AWS API so that we can access AWS resources from our development machine.

#### Create an IAM User

Expand Down Expand Up @@ -149,6 +149,16 @@ If your EC2 instance has the appropriate role (see prerequisites above), and the

As you can see is not necessary to put database credentials to run the application, it gets the necessary values from AWS Secret Manager.

### Using CloudFormation

To run with CloudFormation is not necessary to create any AWS resources, only secrets. Steps are the following

1. Insert your secret properties as explained in section [AWS Secrets Manager](#aws-secrets-manager)
2. As parameters to run your stack, you'll need to specify:
- Database password
- Key Name (for ssh)
3. Go to your application by click to the link given at the output section of the cloudformation after the stack have been created.




Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ cloud.aws.region.static=eu-west-1
cloud.aws.stack.auto=false

# Credentials (unnecessary when running in an EC2 instance with a role having enough permissions for S3 and RDS)
#cloud.aws.credentials.accessKey="key"
#cloud.aws.credentials.accessKey="key"
#cloud.aws.credentials.secretKey="secret"

# In AWS use this instead, and create an EC2 role
cloud.aws.credentials.instanceProfile=true

# S3
cloud.aws.s3.bucket=spring-cloud-aws-sample
cloud.aws.s3.bucket=spring-cloud-aws-sample-s3

0 comments on commit 950c118

Please sign in to comment.