diff --git a/Labs/00-CloudFormation-Stack-Update/README.md b/Labs/00-CloudFormation-Stack-Update/README.md new file mode 100644 index 0000000..2c49f24 --- /dev/null +++ b/Labs/00-CloudFormation-Stack-Update/README.md @@ -0,0 +1,129 @@ +
+ +

+ + cloudofthings + +

100 days in Cloud

+

+ CloudFormation stack update +
+ Lab 0 +
+

+

+ +
+

Lab Details

+
    +
  1. Services covered +
  2. Lab description
  3. + +
  4. Lab date
  5. +
  6. Prerequisites
  7. +
  8. Lab steps
  9. +
  10. Lab files
  11. +
  12. Acknowledgements
  13. +
+
+ +--- + +## Services Covered +* ![cloudformation](https://github.com/CloudedThings/100-Days-in-Cloud/blob/main/images/CloudFormation.png) **CloudFormation** + +--- + +## Lab description +*You have been tasked with the following: +Increasing the size of one of the instances +Allowing HTTP access to the instances from anywhere +Exposing the instance Id of one of the instances as a stack template output* + +--- + +### Learning Objectives +:bulb: **Enable Stack Termination Protection** + +:bulb: **Update template** + +--- + +### Lab date +31-12-2021 + +--- + +### Prerequisites +:cloud: AWS account + +:computer: EC2 Instance running or Terraform installed locally + + +--- + +### Lab steps +1. **Enable Stack Termination Protection**. Using AWS Management Console enable termination protection for the lab CloudFormation stack. + + ![lab00_stack_termination](img/lab00_stack_termination.jpg) + +2. **Update EC2 Instance Type**. + + ``` + TestEc2Instance: + Type: "AWS::EC2::Instance" + Properties: + ImageId: !Ref LatestAmiId + InstanceType: t3.micro + KeyName: !Ref "AWS::AccountId" + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: Ec2InstanceSecurityGroup + SubnetId: !Ref PublicSubnet + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Test Instance + ``` + +3. **Add a Security Group Ingress Rule**. + + ``` + Ec2InstanceSecurityGroup: + Type: "AWS::EC2::SecurityGroup" + Properties: + GroupDescription: Security group for EC2 instances + GroupName: ec2-instance-sg + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + ``` + +4. **Add a Template Output**. + + ``` + ProdEc2Instance: + Description: Instance Id + Value: !Ref ProdEc2Instance + ``` + +5. **Use Specific IAM Role for Updates**. + + ![lab00_iam_role](img/lab00_iam_role.jpg) + +6. Update stack. + + ![lab00_update_stack](img/lab00_update_stack.jpg) + +### Lab files +* [template.json](template.json) + +--- + +### Acknowledgements +* [cloud academy](https://cloudacademy.com/lab-challenge/cloudformation-stack-update-challenge/) + diff --git a/Labs/00-CloudFormation-Stack-Update/img/lab00_diagram.jpg b/Labs/00-CloudFormation-Stack-Update/img/lab00_diagram.jpg new file mode 100644 index 0000000..e15bf09 Binary files /dev/null and b/Labs/00-CloudFormation-Stack-Update/img/lab00_diagram.jpg differ diff --git a/Labs/00-CloudFormation-Stack-Update/img/lab00_iam_role.jpg b/Labs/00-CloudFormation-Stack-Update/img/lab00_iam_role.jpg new file mode 100644 index 0000000..c3bb4cd Binary files /dev/null and b/Labs/00-CloudFormation-Stack-Update/img/lab00_iam_role.jpg differ diff --git a/Labs/00-CloudFormation-Stack-Update/img/lab00_stack_termination.jpg b/Labs/00-CloudFormation-Stack-Update/img/lab00_stack_termination.jpg new file mode 100644 index 0000000..6c467ee Binary files /dev/null and b/Labs/00-CloudFormation-Stack-Update/img/lab00_stack_termination.jpg differ diff --git a/Labs/00-CloudFormation-Stack-Update/img/lab00_update_stack.jpg b/Labs/00-CloudFormation-Stack-Update/img/lab00_update_stack.jpg new file mode 100644 index 0000000..83d7c04 Binary files /dev/null and b/Labs/00-CloudFormation-Stack-Update/img/lab00_update_stack.jpg differ diff --git a/Labs/00-CloudFormation-Stack-Update/template.json b/Labs/00-CloudFormation-Stack-Update/template.json new file mode 100644 index 0000000..94a476e --- /dev/null +++ b/Labs/00-CloudFormation-Stack-Update/template.json @@ -0,0 +1,240 @@ +AWSTemplateFormatVersion: "2010-09-09" + +Description: AWS CloudFormation Stack Update Challenge + +Parameters: + LatestAmiId: + Type: "AWS::SSM::Parameter::Value" + Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 + + PublicSubnetCIDR: + Type: String + Default: "10.192.10.0/24" + Description: IP range (CIDR notation) for the public subnet in the first Availability Zone + + TagPrefix: + Type: String + Default: Challenge Lab + Description: Prefix for tags + + VpcCIDR: + Type: String + Default: "10.192.0.0/16" + Description: IP range (CIDR notation) for the VPC + +Resources: + InternetGateway: + Type: "AWS::EC2::InternetGateway" + Properties: + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Internet Gateway + + VPC: + Type: "AWS::EC2::VPC" + Properties: + CidrBlock: !Ref VpcCIDR + EnableDnsHostnames: true + EnableDnsSupport: true + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Virtual Private Cloud + + Ec2InstanceSecurityGroup: + Type: "AWS::EC2::SecurityGroup" + Properties: + GroupDescription: Security group for EC2 instances + GroupName: ec2-instance-sg + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + + Ec2InstanceSSHSecurityGroup: + Type: "AWS::EC2::SecurityGroup" + Properties: + GroupDescription: SSH Security group for EC2 instances + GroupName: ec2-ssh-instance-sg + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 0.0.0.0/0 + + PublicRouteTable: + Type: "AWS::EC2::RouteTable" + Properties: + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Public Routes + VpcId: !Ref VPC + + InternetGatewayAttachment: + Type: "AWS::EC2::VPCGatewayAttachment" + Properties: + InternetGatewayId: !Ref InternetGateway + VpcId: !Ref VPC + + PublicSubnet: + Type: "AWS::EC2::Subnet" + Properties: + AvailabilityZone: !Select + - 0 + - "Fn::GetAZs": "" + CidrBlock: !Ref PublicSubnetCIDR + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Public Subnet + VpcId: !Ref VPC + + DefaultPublicRoute: + Type: "AWS::EC2::Route" + DependsOn: InternetGatewayAttachment + Properties: + DestinationCidrBlock: "0.0.0.0/0" + GatewayId: !Ref InternetGateway + RouteTableId: !Ref PublicRouteTable + + PublicSubnetRouteTableAssociation: + Type: "AWS::EC2::SubnetRouteTableAssociation" + Properties: + RouteTableId: !Ref PublicRouteTable + SubnetId: !Ref PublicSubnet + + ProdEc2Instance: + Type: "AWS::EC2::Instance" + Properties: + ImageId: !Ref LatestAmiId + InstanceType: t2.micro + KeyName: !Ref "AWS::AccountId" + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: Ec2InstanceSecurityGroup + SubnetId: !Ref PublicSubnet + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Prod Instance + + TestEc2Instance: + Type: "AWS::EC2::Instance" + Properties: + ImageId: !Ref LatestAmiId + InstanceType: t3.micro + KeyName: !Ref "AWS::AccountId" + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: Ec2InstanceSecurityGroup + SubnetId: !Ref PublicSubnet + Tags: + - Key: Name + Value: !Sub ${TagPrefix} Test Instance + + IAMRoleOne: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Principal: + Service: + - cloudformation.amazonaws.com + Action: + - 'sts:AssumeRole' + Path: / + ManagedPolicyArns: + - "arn:aws:iam::aws:policy/AWSCloudFormationFullAccess" + - "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess" + + IAMRoleTwo: + Type: 'AWS::IAM::Role' + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Principal: + Service: + - cloudformation.amazonaws.com + Action: + - 'sts:AssumeRole' + Path: / + ManagedPolicyArns: + - "arn:aws:iam::aws:policy/AWSCloudFormationFullAccess" + - "arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess" + + ChallengeRolePolicy: + Type: "AWS::IAM::Policy" + Properties: + PolicyName: "challenge-role-policy" + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Action: + - "iam:DetachRolePolicy" + - "iam:DeleteRolePolicy" + Resource: + - "arn:aws:iam::*:role/cloudacademylabs-IAMRoleTwo-*" + - "arn:aws:iam::*:role/cloudacademylabs-IAMRoleOne-*" + - Effect: "Allow" + Action: + - "ec2:Describe*" + - "ec2:Get*" + - "ec2:AuthorizeSecurityGroupIngress" + - "ec2:StopInstances" + - "ec2:Delete*" + - "ec2:ModifyInstanceAttribute" + - "ec2:DetachInternetGateway" + - "ec2:DisassociateRouteTable" + - "ec2:TerminateInstances" + - "ec2:StartInstances" + Resource: "*" + - Action: "ec2:RunInstances" + Resource: "arn:aws:ec2:us-west-2:*:instance/*" + Effect: "Allow" + Condition: + StringEquals: + "ec2:InstanceType": + - "t3.micro" + - "t2.micro" + - Action: "ec2:RunInstances" + Effect: "Allow" + Resource: + - "arn:aws:ec2:us-west-2::image/*" + - "arn:aws:ec2:us-west-2::snapshot/*" + - "arn:aws:ec2:us-west-2:*:key-pair/*" + - "arn:aws:ec2:us-west-2:*:security-group/*" + - "arn:aws:ec2:us-west-2:*:subnet/*" + - "arn:aws:ec2:us-west-2:*:network-interface/*" + - "arn:aws:ec2:us-west-2:*:volume/*" + - "arn:aws:ec2:us-west-2:*:placement-group/*" + - "arn:aws:ec2:us-west-2:*:vpc/*" + Roles: + - Ref: "IAMRoleOne" + - Ref: "IAMRoleTwo" + +Outputs: + Ec2InstanceSecurityGroup: + Description: Security group for EC2 instances + Value: !Ref Ec2InstanceSecurityGroup + + ProdEc2Instance: + Description: Instance Id + Value: !Ref ProdEc2Instance + + PublicSubnet: + Description: A reference to the public subnet + Value: !Ref PublicSubnet + + VPC: + Description: A reference to the created VPC + Value: !Ref VPC \ No newline at end of file